1

On Windows OS, we can use right-click on a folder, and it will show property information which will contain folder size information. Now, I want to use Windows API to get a folder size, I do not want to use FindFirstFile/FindNextFile to enumerate all files. Thanks in advance.

I tried below code, however, it returns size with an invalid data.

HANDLE hFile = CreateFile(tsFolderPath.c_str(), GENERIC_READ, FILE_SHARE_READ, 
    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS, NULL); 

LARGE_INTEGER fileSize; 
GetFileSizeEx(hFile, &fileSize);
CloseHandle(hFile);
Jerry YY Rain
  • 4,134
  • 7
  • 35
  • 52
  • You do realize that property page updates "folder size" along with enumerating contained files, don't you? So it still uses `FindFirstFile` you want to avoid. You will have to too. – Roman R. Aug 29 '13 at 06:43
  • What @RomanR. said is true. When you open the property page of a folder that contains thousands of files and sub-folders you will see that the folder size gets updated continuously. – Andreas Aug 29 '13 at 06:46
  • @RomanR. Actually, I tried with enumerating method, however, it seems also not much consistant with OS property result on System disk, (ex. C:\) and I find that because some file with FILE_ATTRIBUTE_REPARSE_POINT is a symbol link which will be counted as twice. however, after I filter it. I find the result is still not same as OS. and there are some file attribute (http://msdn.microsoft.com/en-us/library/windows/desktop/gg258117(v=vs.85).aspx) So what is the correct way? Thanks! – Jerry YY Rain Aug 29 '13 at 07:23
  • How is your example with CreateFile/GetFileSizeEx related to your text including the wish for FindFirstFile/FindNextFile? – harper Aug 29 '13 at 08:39

2 Answers2

3

As far as I know, there is no API function to directly retrieve a folder's size. You have to iterate over the contained files.

Edit: Consider similar questions on SO:

Community
  • 1
  • 1
Sambuca
  • 1,224
  • 18
  • 30
  • 2
    You can see this behaviour, too, in the folder's property dialog: the actual size will increase in the display while the files are iterated. – Thorsten Dittmar Aug 29 '13 at 06:47
2

There are a couple of answers to your question, though one is mostly a technicality.

The first would be to use NtQueryInformationFile (or zwQueryInformationFile) to collect the data. This can return information on all the files in a directory in a single call, avoiding the loop required from the normal functions. Use is somewhat tricky though -- documentation is primarily for device drivers. An application that uses it is a native application instead of Win32. Documentation for this is minimal.

The second possibility would be to write a loop, but instead of FindFirstFile, use FindFirstFileEx. This lets you specify FindExInfoBasic and FIND_FIRST_EX_LARGE_FETCH to optimize the retrieval since you don't need the cAlternateFilename and will be enumerating all the files in the directory, so it should read as much of the relevant data as possible at once.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • For system disk, when enumerate, the total size is not consistant with OS. I find that FILE_ATTRIBUTE_REPARSE_POINT and FILE_ATTRIBUTE_NOT_CONTENT_INDEXED will affect result much. – Jerry YY Rain Aug 29 '13 at 08:07
  • Well, yes, a reparse point has a non-trivial meaning: "this entry does is not a normal file but a reference to one". Higher-level API's respect the semantics, perform the reparse, and will return the size of the referenced file instead of the reference. – MSalters Aug 29 '13 at 09:38