io.Copy() を使用してコピーするとスパース ファイルが大きくなる
io.Copy() を使用してスパース ファイルをコピーすると、予期せずサイズが大きくなる目的地では大きい。これを防ぐにはどうすればよいでしょうか?
バックグラウンド
io.Copy() は、スパース ファイルのプロパティを認識せずに生のバイトを転送します。データに穴が開いたまま、スパース ファイルが効率的に保存されます。 io.Copy() はこのホール情報を伝達できないため、コピー プロセス中にスパース性が失われます。
解決策
この問題に対処するには、バイパスする必要があります。 io.Copy() を使用して、syscall パッケージを直接操作します。方法は次のとおりです:
-
ホールの検出: lseek(2) の SEEK_HOLE および SEEK_DATA 特殊値を使用して、スパース ファイル内のホールとデータ領域を見つけます。
- シーク値のカスタマイズ: プラットフォーム固有の SEEK_HOLE および SEEK_DATA 値が必要です。サポートされているプラットフォームに応じて次の値を決定します。
-
読み取りパターンを変更します。 データを含む領域を特定し、そこからデータを読み取ります。
-
ファイル パンチを検討します。 Linux では、fallocate(2) を使用して宛先ファイルの末尾に穴を開けることを試みることができます。サポートされていない場合は、ゼロ化されたブロックを書き込み、ホールをシミュレートします。
追加の考慮事項
-
ファイルシステムのサポート: すべてのファイルシステムがサポートされているわけではありません。 FAT32 などのホール。宛先ファイル システムがホールをサポートしているかどうかを確認します。
-
ソース ファイルと宛先ファイルの違い: ソース ファイルと宛先ファイルが同じファイル システム上に存在するかどうかを確認します。その場合は、syscall.Rename() または os.Rename() を使用して、コピーせずにファイルを移動することを検討してください。
詳細については、tar アーカイブへのスパース ファイルの書き込みに関する Go の問題 #13548 を参照してください。 .
以上が## io.Copy() でコピーするとスパース ファイルが大きくなるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。