ファイルのコピーがいくつかあります。 _ls -lk
_および_du --apparent-size -k
_によると、ファイルはそれぞれ2390170KiBかかります。
問題は、_du -k
_がコピーごとに異なるサイズ(2389824、2392512、2392512、および2390336)を報告することです。
ディスク使用量は2390172KiB(ファイルが収まる最小ブロック数(597543)のサイズ)であると予想しました。
では、なぜ各ファイルのディスク使用量が異なるのでしょうか。
また、コピーの1つが2389824KiBを使用していることも確認しましたが、ファイルサイズは346KiB大きくなります:2390170。これはどのように意味がありますか?
PD:すべてのファイルは同じext3ファイルシステムにあります。ファイルシステムのブロックサイズは4096です。すべてのファイルのハッシュは同じです。
更新:コメントから:
although the apparent size is usually smaller, it may be larger due to holes in ('sparse') files, internal fragmentation, indirect blocks, and the like
ディスク使用量が少ないため、スパースファイルが原因である可能性があります。しかし、内部の断片化または間接ブロックによって、元のファイルと比較してディスク使用量がどのように減少するかがわかりません。ファイルは同じであるため、内部フラグメンテーションと間接ブロックからのディスク使用量は一定である必要があります。
_cp --sparse=always
_が非スパースファイルからスパースファイルを作成できることを確認しました。 _cp --sparse=always
_ 2390336KiBを使用するファイルの結果_cp --sparse=never
_ 2392512KiBを使用するファイルの結果
したがって、コピーの1つからの2389824KiBの使用は、スパースアルゴリズムの異なる実装が原因であると推測します...
元のファイルはWindowsマシンからsftpまたはsambaを介してコピーされたもので、2389824KiBファイルはそのコピーだと思いますが、どのように作成したかは覚えていません(cpでそれを推測しますが、そうではありません)承知しました)。
man du
から:
-見かけのサイズ
ディスク使用量ではなく、見かけのサイズを出力します。 通常、見かけのサイズは小さくなりますが、(「スパース」)ファイルの穴、内部の断片化、間接ブロックなどのために大きくなる場合があります
info du
から:
'-見かけのサイズ'
ディスク使用量ではなく、見かけのサイズを印刷します。ファイルの見かけのサイズは、通常のファイルでwc -c
によって報告されるバイト数、またはより一般的にはls -l --block-size=1
またはstat --format=%s
です。たとえば、改行のないWord'Zoo 'を含むファイルの見かけのサイズは、もちろん3です。このような小さなファイルには、タイプと構成に応じて、0〜16KiB以上のディスク容量が必要になる場合があります。ファイルが存在するファイルシステムの。ただし、次のコマンドで作成されたスパースファイル:dd bs=1 seek=2GiB if=/dev/null of=big
見かけのサイズは2GiBですが、最近のほとんどのシステムでは、実際にはほとんどディスク領域を使用していません。
[私の強調]
ここで起こっていることが2つあります。予想よりも大きいファイルは、ファイルシステムが保存するメタデータがファイルのサイズにカウントされているためです。予想よりも小さいファイルは、「スパースファイル」と呼ばれるUNIX機能が原因です。
Ext2/ext3の場合、ファイルのディスク上の使用量には、データブロックがディスク上のどこにあるかを追跡するファイルシステム構造によって使用されるスペースが含まれます。 Ext2 iノード構造 を見てください-iノードは、ファイルのパーミッション、サイズなど、およびそのデータブロックがディスク上のどこにあるかを追跡するデータ構造です。 iノード自体は使用量にカウントされません(ファイルシステムの作成時に事前に割り当てられます)が、間接ブロックはカウントされます。
したがって、サイズが2390172kBのファイルは、あなたが言ったように597543ブロックのデータを取ります。これらのブロックのうち12個の場所は、iノード自体に格納されているため、無料です。 iノードに格納されている13番目の場所は、間接ブロック(1024個のデータブロックの場所を格納する新しく割り当てられたブロック)用です。つまり、ファイルサイズに1ブロックが追加され、596507ブロックが残ります。
Iノードの14番目の位置ポインタは、二重間接ブロック(1024個の間接ブロックの位置のスペースを含む割り当てられたブロック)用です。 596507/1024〜 = 582.52なので、残りのデータブロックと1つの二重間接ブロックを含めるには583の間接ブロックが必要になります。
そう:
1 (indirect from inode)
+ 1 (doubly-indirect from inode)
+ 583 (indirect from doubly-indirect)
-----
= 585
= 598128 - 597543
そして、それはサイズ2392512(= 598128 * 4)を占めています。
小さいファイル(2389824kB)はスパースファイルであると思われます。つまり、一部のブロックは書き込まれなかったため、割り当てられませんでした。割り当てられていないブロックは、ゼロで埋められていると定義されます。参考のためにデニスウィリアムソンの答えを参照してください。スパースファイルは、プログラムの書き込みがファイルポインターを移動し、ファイルを最初から最後まで書き込むのではなく、ファイル内の異なる位置に書き込む場合に発生する可能性があります。スパースファイルの極端な例については、次のことを試してください。
du if=/dev/zero of=my_sparse_file bs=1000 count=1 seek=1000000
結果のファイルをls
すると、見かけのサイズは1000001000になります。ただし、書き込まれたのは1000バイトのみであるため、1つのデータブロックのみが使用され、1つのデータブロックのみが割り当てられます。 du
は、使用された12kBを報告します。1つはデータ用の4kブロック、1つは二重間接ブロック用、もう1つは二重間接ブロックが976番目のポインターで指す単一の間接ブロック用です。データであろうとメタデータであろうと、ファイルの残りのブロックは割り当てられませんでした。
二重間接ブロックがなくなると、ファイルシステムは三重間接ブロックの使用を開始します。ファイルがいっぱいになる前に、ファイルは可能な最大のext3ファイルシステムサイズに達します。