私は Linux (UNIX) の低レベル インターフェイスを理解しようとしており、演習として、穴のあるファイルを新しいファイル (再び穴のある) にコピーするコードを書きたいと考えています。
だから私の質問は、最初のファイルから最初の穴までではなく、ファイルの最後まで読み取る方法ですか? 私が間違っていなければread()
、最初の穴(EOF)に到達すると0を返します。
バイトごとに正しいバイトを探してこのバイトを読み取ろうと考えていましたが、事前に穴の数を知る必要があります。
穴とはスパース ファイルを意味する場合、入力ファイルの穴を見つけて、出力ファイルを書き込むときにlseekを使用してそれらを再作成する必要があります。Linux 3.1 以降では、 を使用lseek
してホールの先頭または末尾にジャンプすることもできます。詳細については、man ページを参照してください。
ThiefMasterがすでに指摘しているように、通常のファイル操作では、ホールは単にゼロ バイトのシーケンスとして扱われるため、言及した EOF は表示されません。
ファイルは、ギャップがあるかのように表示されません。open()
ファイルがディスクの 1 つの領域にセクションを持ち、次に別の領域に複数のセクションを持っていることを意図している場合、そのファイルの への呼び出しと一連の呼び出しでこれを確認することはできませんread()
。代わりに、自分でセクターを探して、代わりに生ディスクを使用する必要がopen()
あります。read()
ファイル内の「穴」の意味が @ThiefMaster の言うとおりである場合、0 バイトの領域だけです。これらは、アプリケーションでのデータの使用によると、「穴」にすぎません。ファイルシステムにとって、それらはファイル内の単なるバイトであり、他のものと何ら違いはありません。この場合、データ ソースの単純な読み取りとデータ ターゲットへの書き込みによってデータをコピーできます。完全なコピーが得られます (ホールと呼ばれるものも含まれます)。
スパース ファイルのコピーについては、cp
マニュアルから。
デフォルトでは、スパース SOURCE ファイルは大まかなヒューリスティックによって検出され、対応する DEST ファイルもスパースにされます。それが によって選択された動作--sparse=auto
です。--sparse=always
SOURCE ファイルに十分な長さのゼロ バイト シーケンスが含まれている場合は常に、スパース DEST ファイルを作成するように指定します。--sparse=never
スパース ファイルの作成を禁止するために使用します。
したがって、--sparse=always
スパース ファイルを「そのまま」コピーする必要があるかどうかを試してください (まだアルゴの影響を受けているようです)。