10

多くのゼロを含む大きなファイルがある場合、どうすればそれをスパースファイルにすることができますか?

ファイル全体(スパースに保存される可能性のあるすべてのゼロを含む)を読み取り、ゼロ領域をスキップするシークを使用して新しいファイルに再書き込みする唯一の可能性はありますか?

または、既存のファイル(File.setSparse(long start、long end)など)でこれを作成する可能性はありますか?

JavaまたはいくつかのLinuxコマンドで解決策を探しています。ファイルシステムはext3または同様のものになります。

4

5 に答える 5

13

8年間で多くの変化がありました。

ファロケート

fallocate -d filename既存のファイルに穴を開けるために使用できます。fallocate(1)マニュアルページから:

       -d, --dig-holes
              Detect and dig holes.  This makes the file sparse in-place,
              without using extra disk space.  The minimum size of the hole
              depends on filesystem I/O block size (usually 4096 bytes).
              Also, when using this option, --keep-size is implied.  If no
              range is specified by --offset and --length, then the entire
              file is analyzed for holes.

              You can think of this option as doing a "cp --sparse" and then
              renaming the destination file to the original, without the
              need for extra disk space.

              See --punch-hole for a list of supported filesystems.

(そのリスト:)

              Supported for XFS (since Linux 2.6.38), ext4 (since Linux
              3.0), Btrfs (since Linux 3.7) and tmpfs (since Linux 3.5).

そのリストにあるtmpfsは、私が最も興味深いと思うものです。ファイルシステム自体は、コンテンツを格納するために必要な量のRAMのみを消費するのに十分な効率ですが、コンテンツをスパースにすることで、その効率をさらに高めることができます。

GNUcp

さらに、途中のどこかで、GNUcpはスパースファイルを理解しました。デフォルトモードに関するcp(1)マニュアルページの引用--sparse=auto

スパースソースファイルは大まかなヒューリスティックによって検出され、対応するDESTファイルもスパースになります。

ただし、インプレースで--sparse=always実行するのと同等のファイルコピーをアクティブ化するもあります。fallocate -d

--sparse=alwaysSOURCEファイルにゼロバイトの十分な長さのシーケンスが含まれている場合は常に、スパースDESTファイルを作成するように指定します。

私はついにtar cpSf - SOURCE | (cd DESTDIR && tar xpSf -)ワンライナーを引退させることができました。これは、20年間、スパースファイルをスパース性を維持したままコピーする私の灰色のひげの方法でした。

于 2019-01-29T11:16:24.187 に答える
4

Linux / UNIXの一部のファイルシステムには、既存のファイルに「穴を開ける」機能があります。見る:

それはあまり移植性がなく、全面的に同じように行われるわけではありません。現在のところ、JavaのIOライブラリはこのためのインターフェイスを提供していないと思います。

穴あけがfcntl(F_FREESP)他のメカニズムを介して、または他のメカニズムを介して利用できる場合は、コピー/シークループよりも大幅に高速である必要があります。

于 2011-05-13T10:41:15.843 に答える
2

ファイル全体を事前に割り当てて、占有されているページ/セクションのテーブル/ビットセットを維持する方がよいと思います。

ファイルをスパースにすると、それらのセクションが再利用された場合、それらのセクションが断片化されます。おそらく、数TBのディスク領域を節約することは、高度に断片化されたファイルのパフォーマンスヒットの価値がありません。

于 2011-05-13T09:33:51.370 に答える
0

この記事によると、FIEMAP ioctlを使用する以外に、現在簡単な解決策はないようです。ただし、「非スパース」ゼロブロックを「スパース」ブロックにするにはどうすればよいかわかりません。

于 2011-05-13T09:20:50.690 に答える
0

Linux teminalで使用$ truncate -s filename filesize して、次のようなスパースファイルを作成できます。

メタデータのみ。

注-ファイルサイズはバイト単位です。

于 2012-01-25T05:48:08.513 に答える