io.Copy() による大規模なスパース ファイルの作成: 総合ガイド
ファイルのスパース性の背景
io.Copy() はバイト レベルで動作し、入力ストリームと出力ストリーム間で生データを転送します。ファイルの疎性を処理する機能が欠けています。これは、ファイルに穴 (空き領域) を作成することでデータを効率的に保存する最適化手法です。
io.Copy() の課題
したがって、io.Copy() を使用してスパース ファイルをコピーすると、ホール構造を保存するメカニズムがないため、宛先ファイルが大きくなります。 io.Copy() は、空の領域が含まれている場合でも、スパース ファイルをデータで埋められているかのように扱います。
Syscall を使用した回避策
この制限を克服するには、次の方法があります。 io.Copy() をバイパスし、syscall パッケージを使用してファイルのコピーを手動で実装する必要があります。具体的には、SEEK_HOLE 値と SEEK_DATA 値を lseek(2) と組み合わせて使用し、ソース ファイル内のホールとデータを特定する必要があります。
プラットフォーム固有の考慮事項
SEEK_HOLE および SEEK_DATA の値はプラットフォームによって異なるため、ターゲット システムに応じた特定の値を決定することが重要です。これらの値は、ヘッダー ファイルまたはシステム ドキュメントから取得できます。たとえば、Linux システムでは通常、これらの値を /usr/include/unistd.h で定義します。
プラットフォーム固有のファイルの作成
プラットフォームの互換性を確保するには、次のことをお勧めします。 SEEK_HOLE 値と SEEK_DATA 値を含むプラットフォーム固有のファイルを作成します。これにより、開発者はコア コードを変更せずに、異なるプラットフォーム間で簡単に切り替えることができます。
スパース ファイルの読み取り手順
スパース ファイルを読み取るとき、重要なのはデータを識別することです。領域を含み、それらの領域からデータを読み取ります。これには、SEEK_HOLE を使用して次のデータ領域をシークし、SEEK_DATA を使用して次のホールに到達するまでデータを読み取ることが含まれます。
スパース ファイルの転送
スパース ファイルをスパースとして転送するには、追加のステップ。ターゲット ファイルシステムに応じて、fallocate(2) を使用して宛先ファイルにホールを作成することができます。 fallocate(2) がサポートされていない場合は、ゼロ化されたブロックでホールを埋め、オペレーティング システムがそれらを実際のホールに変換することを期待できます。
ファイルシステムの考慮事項
一部のファイルシステムはホールをサポートしていないことに注意することが重要です。ターゲット ファイルシステムがこのカテゴリに分類される場合、この手法を使用してスパース ファイルを作成することはできません。
追加のヒント
以上がio.Copy() が大きなスパース ファイルを作成するのはなぜですか?また、スパース性を維持しながらファイルを効率的にコピーするにはどうすればよいでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。