Search code examples
c++windowswinapintfsdiskspace

Windows Get list of ALL files on volume with size


Question: how to list all files on volume with size they occupy on disk?

Applicable solutions:

  • cmd script
  • free tool with sqlite/txt/xls/xml/json output
  • C++ / winapi code

The problem:

There are many tools and apis to list files, but their results dont match chkdsk and actual free space info:

                                     Size              Count (x1000)
chkdsk c:                            67 GB             297
dir /S                               42 GB             267                
FS Inspect                           47 GB             251
Total Commander (Ctrl+L)             47 GB             251
explorer (selection size)            44 GB             268
explorer (volume info)               67 GB             -
WinDirStat                           45 GB             245
TreeSize                             couldn't download it - site unavailable
C++ FindFirstFile/FindNextFile       50 GB             288
C++ GetFileInformationByHandleEx     50 GB             288

Total volume size is 70 GB, about 3 GB is actually free.

I'm aware of:

  • File can occupy on disk, more than its actual size, i need the size it occupies (i.e. greater one)
  • Symlinks, Junctions etc - that would be good to see them (though i don't think this alone can really give 20 GB difference in my case)
  • Filesystem uses some space for indexes and system info (chkdisk shows negligible, don't give 20 GB)
  • I run all tools with admin privileges, hidden files are shown.
  • FindFirstFile/FindNextFile C++ solution - this dont give correct results, i don't know because of what, but this gives the same as Total commander NOT the same as chkdsk

Practical problem:

I have 70 GB SSD disk, all the tools report about 50 GB is occupied, but in fact it's almost full. Format all and reinstall - is not an option since this will happens again quite soon.

I need a report about filesizes. Report total must match actual used and free space. I'm looking for an existing solution - a tool, a script or a C++ library or C++ code.

(Actual output below)

chkdsk c:

Windows has scanned the file system and found no problems.
No further action is required.

  73715708 KB total disk space.
  70274580 KB in 297259 files.
    167232 KB in 40207 indexes.
         0 KB in bad sectors.
    463348 KB in use by the system.
     65536 KB occupied by the log file.
   2810548 KB available on disk.

      4096 bytes in each allocation unit.
  18428927 total allocation units on disk.
    702637 allocation units available on disk.

dir /S

Total Files Listed:
    269966 File(s) 45 071 190 706 bytes
    143202 Dir(s)   3 202 871 296 bytes free

FS Inspect http://sourceforge.net/projects/fs-inspect/

47.4 GB 250916 Files

Total Commander

49709355k, 48544M 250915 Files

Solution

  • On a Posix system, the answer would be to use the stat function. Unfortunately, it does not give the number of allocated blocs in Windows so it does not meet your requirements.

    The correct function from Windows API is GetFileInformationByHandleEx. You can use FindFirstFile, FindNextFile to browse the full disk, and ask for FileStandardInfo to get a FILE_STANDARD_INFO that contains for a file (among other fields): LARGE_INTEGER AllocationSize for the allocated size and LARGE_INTEGER EndOfFile for the used size.

    Alternatively, you can use directly GetFileInformationByHandleEx on directories, asking for FileIdBothDirectoryInfo to get a FILE_ID_BOTH_DIR_INFO structure. This allows you to get information on many files in a single call. My advice would be to use that one, even if it is of less common usage.