I need to get a count of the number of files in a directory. I could get the names of all the files in the directory using System.IO.Directory.GetFiles()
and take the length of that array but that takes too long on large directories. Is there a way to get just the count without having to get the names?
我需要计算目录中的文件数。我可以使用System.IO.Directory.GetFiles()获取目录中所有文件的名称,并获取该数组的长度,但在大型目录上需要太长时间。有没有办法获得计数而不必得到名字?
4 个解决方案
#1
14
I don't believe so, no - at least not in vanilla .NET. I suspect it's not the actual fetching of the names that takes the time - it's the OS walking through the directory internals. There may be a Win32 call you could make via P/Invoke.
我不相信,不 - 至少不是在vanilla .NET中。我怀疑这不是实际获取名称花费时间 - 这是操作系统遍历目录内部。您可以通过P / Invoke进行Win32调用。
How large is the directory you're looking at? In general it's at least traditionally not been a good idea to have more than a few hundred files in a directory. File systems have improved at this in general, but I don't know what the current state is with NTFS and Fat32.
你正在查看的目录有多大?一般来说,在目录中拥有超过几百个文件至少在传统上并不是一个好主意。文件系统在这方面有所改进,但我不知道NTFS和Fat32的当前状态。
#2
7
I did a little test - wrote the same task in C++/Qt and C++/CLI:
我做了一点测试 - 在C ++ / Qt和C ++ / CLI中编写了相同的任务:
LARGE_INTEGER i1, i2;
QueryPerformanceCounter(&i1);
int count = IO::Directory::GetFiles(L"c:\\windows\\system32")->Length;
QueryPerformanceCounter(&i2);
__int64 result = i2.QuadPart - i1.QuadPart;
Result is about 16.500.000
结果大约是16.500.000
and
LARGE_INTEGER i1, i2;
QueryPerformanceCounter(&i1);
intcount = QDir("c:/windows/system32").entryList(QDir::Files).count();
QueryPerformanceCounter(&i2);
__int64 result += i2.QuadPart - i1.QuadPart;
Result is about 2.100.000.000
结果大约是2.100.000.000
Files count is 2125
文件数量为2125
#3
3
There is no faster way. No matter what you use, it all boils down to FindFirstFile
and FindNextFile
Win32 calls.
You could try using something like this, but it will probably take just as much time -- but maybe with a little less memory usage (= probably not worth it).
没有更快的方法。无论你使用什么,它都归结为FindFirstFile和FindNextFile Win32调用。你可以尝试使用这样的东西,但它可能需要花费同样多的时间 - 但可能会少用一点内存(=可能不值得)。
#4
1
So far, in most languages I came across, you get this information only by walking the folder and counting the files. I doubt there is a Windows API call to get only the count (but I can be surprised!).
Advantage of the method: flexibility - you can filter out some file types, walk down recursively or ignore folders, etc.
到目前为止,在我遇到的大多数语言中,只有通过遍历文件夹并计算文件才能获得此信息。我怀疑有一个Windows API调用只能获得计数(但我可能会感到惊讶!)。方法的优点:灵活性 - 您可以过滤掉一些文件类型,递归地向下走或忽略文件夹等。
If the method is slow for you, maybe you should get a better method, like not creating an array filled with directory info (takes time to fill it! not to mention memory cost and garbage collection time) but using an iterator: a bit more work (but once you get the function, it is always there) but much more efficient.
如果方法对你来说很慢,也许你应该得到一个更好的方法,比如不创建一个充满目录信息的数组(需要时间来填充它!更不用说内存成本和垃圾收集时间)但是使用迭代器:多一点工作(但是一旦你获得了这个功能,它总是在那里)但效率更高。
#1
14
I don't believe so, no - at least not in vanilla .NET. I suspect it's not the actual fetching of the names that takes the time - it's the OS walking through the directory internals. There may be a Win32 call you could make via P/Invoke.
我不相信,不 - 至少不是在vanilla .NET中。我怀疑这不是实际获取名称花费时间 - 这是操作系统遍历目录内部。您可以通过P / Invoke进行Win32调用。
How large is the directory you're looking at? In general it's at least traditionally not been a good idea to have more than a few hundred files in a directory. File systems have improved at this in general, but I don't know what the current state is with NTFS and Fat32.
你正在查看的目录有多大?一般来说,在目录中拥有超过几百个文件至少在传统上并不是一个好主意。文件系统在这方面有所改进,但我不知道NTFS和Fat32的当前状态。
#2
7
I did a little test - wrote the same task in C++/Qt and C++/CLI:
我做了一点测试 - 在C ++ / Qt和C ++ / CLI中编写了相同的任务:
LARGE_INTEGER i1, i2;
QueryPerformanceCounter(&i1);
int count = IO::Directory::GetFiles(L"c:\\windows\\system32")->Length;
QueryPerformanceCounter(&i2);
__int64 result = i2.QuadPart - i1.QuadPart;
Result is about 16.500.000
结果大约是16.500.000
and
LARGE_INTEGER i1, i2;
QueryPerformanceCounter(&i1);
intcount = QDir("c:/windows/system32").entryList(QDir::Files).count();
QueryPerformanceCounter(&i2);
__int64 result += i2.QuadPart - i1.QuadPart;
Result is about 2.100.000.000
结果大约是2.100.000.000
Files count is 2125
文件数量为2125
#3
3
There is no faster way. No matter what you use, it all boils down to FindFirstFile
and FindNextFile
Win32 calls.
You could try using something like this, but it will probably take just as much time -- but maybe with a little less memory usage (= probably not worth it).
没有更快的方法。无论你使用什么,它都归结为FindFirstFile和FindNextFile Win32调用。你可以尝试使用这样的东西,但它可能需要花费同样多的时间 - 但可能会少用一点内存(=可能不值得)。
#4
1
So far, in most languages I came across, you get this information only by walking the folder and counting the files. I doubt there is a Windows API call to get only the count (but I can be surprised!).
Advantage of the method: flexibility - you can filter out some file types, walk down recursively or ignore folders, etc.
到目前为止,在我遇到的大多数语言中,只有通过遍历文件夹并计算文件才能获得此信息。我怀疑有一个Windows API调用只能获得计数(但我可能会感到惊讶!)。方法的优点:灵活性 - 您可以过滤掉一些文件类型,递归地向下走或忽略文件夹等。
If the method is slow for you, maybe you should get a better method, like not creating an array filled with directory info (takes time to fill it! not to mention memory cost and garbage collection time) but using an iterator: a bit more work (but once you get the function, it is always there) but much more efficient.
如果方法对你来说很慢,也许你应该得到一个更好的方法,比如不创建一个充满目录信息的数组(需要时间来填充它!更不用说内存成本和垃圾收集时间)但是使用迭代器:多一点工作(但是一旦你获得了这个功能,它总是在那里)但效率更高。