19

サイズがそれぞれ 100G の 2 つのファイルがあるとします。そして、それらを1つにマージしてから削除したいと思います。Linuxでは、使用できます

cat file1 file2 > final_file

ただし、2 つの大きなファイルを読み取ってから、より大きなファイルを書き込む必要があります。IO が不要になるように、あるファイルを別のファイルに追加することは可能ですか? ファイルのメタデータにはファイルの場所と長さが含まれているため、ファイルのメタデータを変更してマージを実行できるかどうか疑問に思っているため、IO は発生しません。

4

3 に答える 3

30

一方のファイルに他方のファイルを書き込まずに、2 つのファイルをマージできますか?

あいまいな理論でのみ。ディスクストレージは常にブロックに基づいており、ファイルシステムはブロック境界に物事を格納するため、最初のファイルがブロック境界で完全に終了した場合にのみ、1 つのファイルを別のファイルに追加することができます。テール パッキングを使用するまれなファイル システム構成がいくつかありますが、これは、最初のファイルが前のファイルのテール ブロックを既に使用している場合にのみ役立ちます。

その完璧なシナリオが発生するか、ファイルシステムがファイルの途中で部分ブロックをマークできない限り (これは聞いたことがありません)、これは機能しません。エッジケースをキックするだけで、カーネルインターフェイスを変更してそのような呼び出しを行う以外に方法はありません(re:特定のinodeへのリンク

両方のファイルのサイズを 2 倍にするよりも、これを改善できますか?

はい、代わりに追加 ( >>) 操作を使用できます。

cat file2 >> file1

file2その結果、削除できるようになるまで、消費されたすべてのスペースを2 倍以上使用することになります。

余分なスペースの使用を避けることはできますか?

いいえ。誰かが私が知らない何かを持って戻ってこない限り、あなたは基本的に運が悪い. ファイルの終わりの存在を忘れてファイルを切り詰めることは可能ですが、inode を直接変更してファイルシステムへのカーネル インターフェイスを変更しなければならない場合を除き、最初の存在を忘れる方法はありません。間違いなくPOSIX操作ではありません。

一度に少しずつ書いてから、書いたものを削除するのはどうですか?

いいえ。ファイルの先頭を切り取ることはできないため、関心のあるポイントからファイルの末尾まですべてを書き直す必要があります。これは IO にとって非常にコストがかかり、ファイルの半分を既に読み取った後にのみ役立ちます。

スパースファイルはどうですか?

多分!スパース ファイルを使用すると、ほとんどスペースを使い果たすことなく、ゼロの長い文字列を格納できます。最後から始まる大きなチャンクで読み取る場合はfile2、それらのブロックを の最後に書き込むことができますfile1file1両方と同じサイズであるかのようにすぐに見えます (そして読み取られます) が、書き込みが完了するまで破損します。

これをすべて説明すること自体は別の答えですが、予備の割り当てを行うことができれば、チャンクの読み取りサイズ + ディスク領域のわずかな追加分だけを使用して、この操作を実行できます。ファイルの途中にあるまばらなブロックについて言及しているリファレンスについては、http://lwn.net/Articles/357767/を参照するか、用語SEEK_HOLE.

なぜこれは「はい」ではなく「たぶん」なのですか?2 つの部分: 独自のツールを作成する必要があります (少なくとも、私たちはそのための適切なサイトにいます)。また、スパース ファイルは、ファイル システムや他のプロセスによって普遍的に尊重されるわけではありません。幸いなことに、ファイルを尊重する他のプロセスについて心配する必要はおそらくありませんが、正しいフラグを設定し、ファイルシステムが適切であることを確認することについて心配する必要があります。最後に、あなたはまだ の長さを読んで書き直していますがfile2、これはあなたが望むものではありません. ただし、この方法は、少なくともディスク容量を使用するのではなく、少量のディスク容量で追加できることを意味します2*file2

于 2012-11-16T06:01:47.543 に答える
7

あなたはこのようにすることができます

cat file2 >> file1

file1 が完全なコンテンツになります。

于 2012-11-16T05:48:05.323 に答える
1

いいえ、メタデータを操作して2つの大きなファイルを(Linuxで)マージすることはできません。

多分あなたはあなたの仕事のためにある種のデータベースを検討するかもしれません。

アレクサンドルが気付いたように、ある大きなファイルを別のファイルに追加することはできますが、それでも多くのデータをコピーする必要があります。

于 2012-11-16T05:47:56.910 に答える