Go でのファイル コピー: 基本を超えて
Go でのファイル コピーの単純さは誤解を招く可能性があります。 os.Link() 関数は効率的であると称されるメソッドを提供しますが、その制限により、より包括的なアプローチが必要になります。
Link() Quirks
Os.Link() 2 つのファイル間のハード リンクにより、バイト転送のオーバーヘッドが回避されます。ただし、このアプローチには固有の制限があります。オペレーティング システムが異なると、ハード リンクにさまざまな制約が課されます。特定のシナリオでは、Link() 呼び出しが失敗することがあります。
堅牢なファイル コピー
堅牢で効率的なコピーを行うには、次の手順をお勧めします。
場合によっては、同期 (ブロッキング) と非同期 (ノンブロッキング) の別々の関数
最適化された例
次のコード スニペットは、推奨される手順を組み込んだ包括的なファイル コピー関数 CopyFile() を実装します。
package main import ( "fmt" "io" "os" ) // CopyFile implements a robust and efficient file copy. func CopyFile(src, dst string) (err error) { sfi, err := os.Stat(src) if err != nil { return err } if !sfi.Mode().IsRegular() { return fmt.Errorf("CopyFile: Non-regular source file %s (%q)", sfi.Name(), sfi.Mode()) } dfi, err := os.Stat(dst) if err != nil { if os.IsNotExist(err) { return nil // Destination file doesn't exist, so no copying required. } return err } if !(dfi.Mode().IsRegular()) { return fmt.Errorf("CopyFile: Non-regular destination file %s (%q)", dfi.Name(), dfi.Mode()) } if os.SameFile(sfi, dfi) { return nil // Files are identical, so no copying required. } if err = os.Link(src, dst); err == nil { return nil // Hard link succeeded. } err = copyFileContents(src, dst) return err } // copyFileContents performs a byte-wise copy of the source file to the destination file. func copyFileContents(src, dst string) error { in, err := os.Open(src) if err != nil { return err } defer in.Close() out, err := os.Create(dst) if err != nil { return err } defer func() { if err == nil { err = out.Close() } }() if _, err = io.Copy(out, in); err != nil { return err } return out.Sync() }
この機能は、効率性、堅牢性、さまざまなエッジケースへの対応を組み合わせています。
以上がGo Beyond os.Link() で堅牢かつ効率的なファイル コピーを実現するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。