检查文件夹是否有文件
我有一个程序可以将哪些文件夹已满或为空写入数据库。现在我在用
bool hasFiles=false;
(Directory.GetFiles(path).Length >0) ? hasFiles=true: hasFiles=false;
但是需要快一个小时,而且这段时间我什么也做不了。
有没有最快的方法来检查文件夹是否有文件?
I have program which writes to database which folders are full or empty. Now I'm using
bool hasFiles=false;
(Directory.GetFiles(path).Length >0) ? hasFiles=true: hasFiles=false;
but it takes almost one hour, and I can't do anything in this time.
Is there any fastest way to check if folder has any file ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
要检查目录或子目录中是否存在任何文件,在.net 4中,您可以使用以下方法:
To check if any files exists inside the directory or sub directories, in .net 4, you can use method below:
加速这种跨网络搜索的关键是减少跨网络的请求数量。与其获取所有目录,然后检查每个目录中的文件,不如尝试通过一次调用获取所有内容。
在 .NET 3.5 中,没有一种方法可以递归获取所有文件和文件夹,因此您必须自己构建它(见下文)。在 .NET 4 中,新的重载可以一步实现这一点。
使用
DirectoryInfo
还可以获取有关返回的名称是文件还是目录的信息,这也减少了调用。这意味着拆分所有目录和文件的列表将变成如下所示:
实现
GetAllFileSystemObjects
取决于 .NET 版本。在 .NET 4 上,这非常简单:在早期版本上需要做更多的工作:
这种方法尽可能少地调用文件系统,在 .NET 4 上仅调用一次,或者在早期版本上每个目录调用一次,从而允许网络客户端和服务器以最大限度地减少底层文件系统调用和网络往返的数量。
获取 FileSystemInfo 实例的缺点是需要多个文件系统操作(我相信这在某种程度上依赖于操作系统),但对于每个名称,任何解决方案都需要知道它是文件还是目录,因此这是不可避免的在某种程度上(不诉诸
FindFileFirst
/FindNextFile
/FindClose
的 P/Invoke)。除此之外,使用分区扩展方法会更容易:
将其编写为惰性将是一项有趣的练习(仅当某个输出迭代一个输出时才消耗输入,同时缓冲另一个输出)。
The key to speeding up such a cross-network search is to cut down the number of requests across the network. Rather than getting all the directories, and then checking each for files, try and get everything from one call.
In .NET 3.5 there is no one method to recursively get all files and folders, so you have to build it yourself (see below). In .NET 4 new overloads exist to to this in one step.
Using
DirectoryInfo
one also gets information on whether the returned name is a file or directory, which cuts down calls as well.This means splitting a list of all the directories and files becomes something like this:
Implementing
GetAllFileSystemObjects
depends on the .NET version. On .NET 4 it is very easy:On earlier versions a little more work is needed:
This approach calls into the filesystem as few times as possible, just once on .NET 4 or once per directory on earlier versions, allowing the network client and server to minimise the number of underlying filesystem calls and network round trips.
Getting
FileSystemInfo
instances has the disadvantage of needing multiple file system operations (I believe this is somewhat OS dependent), but for each name any solution needs to know if it is a file or directory so this is not avoidable at some level (without resorting to P/Invoke ofFindFileFirst
/FindNextFile
/FindClose
).Aside, the above would be easier with a partition extension method:
Writing that to be lazy would be an interesting exercise (only consuming input when something iterates over one of the outputs, while buffering the other).
如果您使用 .Net 4.0,请查看 EnumerateFiles 方法。
http://msdn.microsoft.com/en -us/library/dd413232(v=VS.100).aspx
这样,并非从文件夹中检索所有文件,如果枚举器至少有 1 个文件,则文件夹不为空
If you are using .Net 4.0 have a look at the EnumerateFiles method.
http://msdn.microsoft.com/en-us/library/dd413232(v=VS.100).aspx
This way not all the files are retrieved from the folder, if the enumerator has at least 1 file the folder is not empty
我假设(尽管我不确定)因为您在网络驱动器上调用 GetFiles(),所以从所有 30k 文件夹中检索所有文件并枚举它们会增加相当多的时间。
我在此处找到了替代目录枚举器在 CodeProject 上,看起来很有希望。或者...您可以在服务器上创建一个 WebService,为您枚举所有内容并返回结果。
编辑:我认为您的问题更可能是文件夹访问。每次访问网络驱动器中的目录时,您都会遇到安全和权限检查。 * 30k 文件夹将对性能造成很大影响。我非常怀疑使用 FindFirstFile 会有多大帮助,因为枚举的实际文件数只会是 0 或 1。
I'm assuming (although I don't know for definite) that because you're calling GetFiles() on a network drive it adds considerable time to retrieve all the files from all 30k folders and enumerate through them.
I've found an alternative Directory Enumerator here on CodeProject which looks promising.Alternatively... you could create a WebService on the server that enumerates everything for you and returns the results after.
EDIT: I think your problem is more likely the folder access. Each time you access a Directory in the network drive you're going to be hitting security and permission checks. That * 30k folders will be a big performance hit. I highly doubt using the FindFirstFile will help much as the actual number of files enumerated will only ever be 0 or 1.
可能值得一提的是:
您是在主线程上从 GUI 应用程序执行此操作吗?如果是这样,请使用
BackgroundWorker
结束此过程。至少这样应用程序将继续响应。您还可以在该方法中添加对CancellationPending
的检查,并在花费太长时间时取消它。有点与你的问题无关——只是我注意到并认为我会发表评论的事情。
Might be worth mentioning:
Are you doing this from a GUI app, on the main thread? If so, spit this process off using a
BackgroundWorker
. At least then the app will continue to be responsive. You could also add checks forCancellationPending
in the method and cancel it if it's taking too long.Kind of tangential to your question--just something I noticed and thought I'd comment on.
最好的选择是使用 API 函数 FindFirstFile。那样就不会花那么长时间了。
Your best bet is to use the API function FindFirstFile. It wont take nearly as long then.