使用boost::filesystem的C++目录大小工具与du结果不符求助
du (But Matches Nautilus) Hey there, let's unpack why you're seeing this mismatch between your C++ tool and the du command—great catch that Nautilus aligns with your results, that's a key clue! Here are the most common reasons for this discrepancy:
1. Apparent Size vs. Disk Block Usage
This is the #1 culprit.
- Your tool (and Nautilus) uses
boost::filesystem::file_size(), which returns the actual logical size of the file (the number of bytes the file contains). - The default
ducommand reports the disk space actually occupied by the file. Since files are stored in fixed-size disk blocks (usually 4KB on most systems), even a 1-byte file will take up an entire block. Soducounts that as 4KB, while your tool shows 1 byte.
To verify this, run du --apparent-size on the same directory—this makes du report logical size, and it should match your tool's output perfectly.
2. Sparse Files Handling
If your directory contains sparse files (files with large empty sections marked as unallocated), this amplifies the above issue:
file_size()returns the full logical size (e.g., 1GB for a sparse file that only uses 1MB of disk space).- Default
dureturns the actual disk space used (1MB in this example). Again,du --apparent-sizewill match your results.
3. Symbolic Link Behavior
Double-check how your tool handles symlinks:
boost::filesystem::directory_iteratordoesn't follow symbolic links by default. So your tool counts the symlink itself (a tiny file, usually a few dozen bytes) rather than the file/directory it points to.- By default,
dualso doesn't follow symlinks—but if you accidentally randu -L(which follows symlinks), that would cause a mismatch. Conversely, if your tool is configured to follow symlinks butduisn't, that would also explain the difference.
Debugging Steps to Pinpoint the Issue
- Pick a small directory where the difference is obvious. Compare your tool's output with both
duanddu --apparent-size—this will immediately tell you if block size is the problem. - For individual files, run
stat <file>: look atSize(logical size, matches your tool) vsBlocks(disk blocks used, matches defaultdu). - If symlinks are suspect, test with a directory containing a symlink: check if your tool counts the symlink itself or follows it, then compare with
duanddu -L.
If you want your tool to match du's default behavior, you can calculate the disk block usage manually using boost::filesystem::space() to get the block size, then compute each file's occupied blocks as (file_size + block_size - 1) / block_size, then multiply by block size to get the total.
内容的提问来源于stack exchange,提问作者jelmew

