Go でスパース ファイルを肥大化させずに効率的にコピーするにはどうすればよいですか?

Barbara Streisand
リリース: 2024-11-03 17:06:02
オリジナル
647 人が閲覧しました

How Do You Efficiently Copy Sparse Files in Go Without Bloating?

io.Copy() で膨張するスパース ファイル

io.Copy() でファイルをコピーすると、大きなスパース ファイルが不釣り合いに膨張する傾向があります彼らの目的地で。この動作は、io.Copy() による raw バイトの処理に起因しており、ファイル ホールに関する情報を伝達する手段がありません。

ホールの処理

ホールを管理するにはの場合は、syscall パッケージをさらに詳しく調べて、lseek(2) の SEEK_HOLE および SEEK_DATA の値をいじる必要があります。残念ながら、これらの値は、標準の syscall パッケージやそれに対応する golang.org/x/sys には存在しません。

解決策

これを解決するには、次の手順に従います。

  1. サポートされているプラ​​ットフォームで syscall.Seek() を lseek(2) にマップします。
  2. ターゲット プラットフォームの SEEK_HOLE と SEEK_DATA の正しい値は異なる可能性があるため、決定します。

たとえば、Linux では、以下を使用できます。

// +build linux

const (
    SEEK_DATA = 3
    SEEK_HOLE = 4
)
ログイン後にコピー

スパース ファイルの読み取りと転送

データ領域の検出と読み取りスパースファイルの読み取り中にそれらを実行します。スパース性を維持したままファイルを転送する場合、プロセスはより複雑であり、プラットフォーム固有の考慮事項が必要です。

Linux 固有のアプローチ

Linux では、fallocate(2) を次のように使用します。 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE を使用して、ファイルの末尾に穴を開けます。失敗した場合は、ゼロ化されたブロックをシャベルして穴を隠します。

追加メモ

  • FAT などの一部のファイル システムは、ホールをサポートしていません。
  • データをコピーせずにファイルを高速に移動するには、syscall.Rename() の使用を検討するには、ソースと宛先が同じファイルシステム上にあるかどうかを確認してください。

以上がGo でスパース ファイルを肥大化させずに効率的にコピーするにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート