
次のように作成されたファイルを想像してください:
truncate -s1T file
echo test >> file
truncate -s2T file
現在、2 テビバイトのファイル (ディスク上で 4 キロバイトを占有) があり、"test\n"
その中央に書き込みがあります。
"test"
ファイル全体を読み取らずに、効率的に回復するにはどうすればよいでしょうか。
tr -d '\0' < file
結果は得られますが、それには何時間もかかります。
私が欲しいのは、ファイルの非スパース部分のみを出力するものです (つまり、上記のみ、"test\n"
またはおそらく、そのデータを格納するディスクに割り当てられた 4kiB ブロックのみ)。
ファイルのどの部分が割り当てられた(FIBMAP、FIEMAP、SEEK_HOLE、SEEK_DATA...) ですが、これらを公開するツールは何ですか?
移植可能なソリューション(少なくともこれらの API をサポートする OS に対して)が望まれます。
答え1
これまでのところ、私が思いついた最善の方法は、(ksh93、1.42.9filefrag
以降を使用e2fsprogs
(一部の古いバージョンでは API が異なります)、Linux のエクステント ベースのファイル システムの場合) です。
#! /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 ファイルを解析して非スパース セクションを取得する必要があります。