ここには不正確さや信頼性の問題はありません。論理サイズと物理サイズの 2 つの異なる数値を比較しているだけです。
スパース ファイルのウィキペディアの図は次のとおりです。

ls ファイルの論理的な長さである灰色と緑色の領域を示します。 du (--apparent-size なし) ) は緑色の領域のみを示しています。これらはスペースを占有する領域であるためです。
dd count=0 bs=1M seek=100 of=myfile でスパースファイルを作成できます .
ls ファイルの長さが 100MiB であるため、
$ ls -lh myfile
-rw-r----- 1 me me 100M Jul 15 10:57 myfile
du 割り当てられているデータ量が 0 であるため、0 と表示されます:
$ du myfile
0 myfile
ls -l --block-size=M
長い形式のリスト (実際にファイル サイズを確認する必要があります) が表示され、ファイル サイズが最も近い MiB に丸められます。 .
MB が必要な場合 MiB ではなく (10^6 バイト) (2^20 バイト) 単位、--block-size=MB を使用
M が必要ない場合 ファイルサイズに付けられた接尾辞、 --block-size=1M のようなものを使用できます .これを提案してくれた Stéphane Chazelas に感謝します。
これは、ls の man ページで説明されています。; man ls SIZE を検索します . MB/MiB 以外の単位を許可します 同様に、その外観から (私はそれを試していません) 任意のブロック サイズも同様です (そのため、必要に応じて、ファイル サイズを 412 バイト ブロックの数として表示できます)。
--block-size に注意してください パラメータは、Open Group の ls の上にある GNU 拡張です。 、したがって、GNU ユーザーランドがない場合、これは機能しない可能性があります (ほとんどの Linux インストールではそうです)。 GNU coreutils 8.5 の ls は --block-size をサポートします
他の guiy の回答とスパース ファイルに関するウィキページの図で説明されているように、ファイル サイズにはいくつかの概念があります。
ただし、ls(1) と stat(1) コマンドの両方を使用したい場合があります。
C でコーディングする場合は、stat(2) &lseek(2) システムコールの使用を検討してください。
この回答の参照も参照してください。