tags:

views:

932

answers:

4

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?

+7  A: 

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.

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.

Jon Skeet
Indeed, the filesystem itself does not keep the count. It must count the entire list to find the count - which is why it takes the same amount of time.
configurator
+1  A: 

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.

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.

PhiLho
+2  A: 

I did a little test - wrote the same task in C++/Qt and 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

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

Files count is 2125

abatishchev
+2  A: 

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).

Vincent Van Den Berghe