スパースファイルの非スパース部分を表示する方法は?


8

次のように作成されたファイルを想像してください。

truncate -s1T file
echo test >> file
truncate -s2T file

現在、2テビバイトのファイル(ディスク上で4kiBを占めています)"test\n"があり、中央に書き込まれています。

それを"test"効率的に回復するにはどうすればよいでしょうか。つまり、ファイル全体を読み取る必要がありません。

tr -d '\0' < file

結果は出ますが、それは数時間かかります。

"test\n"が欲しいのは、ファイルの非スパース部分のみを出力するものです(そのため、そのデータを格納するディスクに割り当てられた4kiBブロックのみまたはそれ以上の可能性があります)。

ファイルのどの部分が割り当てられているかを確認するAPI (FIBMAP、FIEMAP、SEEK_HOLE、SEEK_DATA ...)がありますが、それらを公開しているツールは何ですか?

ポータブルソリューション(少なくともこれらのAPIをサポートするOSにとって)が評価されます。


どのくらい効率的ですstringsか?
グレンジャックマン2014年

@glennjackman、trそれでもファイル全体を読み取り、NULバイトを削除する以上のことを行うので、より少ないです。
ステファンChazelas

回答:


6

私がこれまでに思いつくことができる最高のものは(Linux上のエクステントベースのファイルシステムでfilefrage2fsprogs1.42.9 から使用するksh93(一部の古いバージョンは異なるAPIを持っている)です):

#! /bin/ksh93
export LC_ALL=C
for file do
filefrag -vb1 -- "$file" |
  while IFS=": ." read -A a; do
    [[ $a = +([0-9]) ]] && [[ ${a[@]} != *unwritten* ]] &&
      command /opt/ast/bin/head -s "${a[1]}" -c "${a[7]}" -- "$file"
  done
done

filefrag それをサポートするファイルシステムのFIEMAP ioctlを使用してファイルの範囲を報告します。

この*unwritten*部分は、fallocated書き込まれたことのない(スパースではないが、まだ興味のないゼロでいっぱいの)ファイルをカバーしています。

bsdtarまたはの最近のバージョンではstar、これらのAPIの一部を使用してtar、スパースセクションを識別するファイルを生成できます。これはよりポータブルなソリューションになりますが、非スパースセクションを取得するには、生成されたtarファイルを解析する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.