Goでファイルをコピーする方法(Golang)
Takashi Yamamoto
Infrastructure Engineer · Leapcell

Key Takeaways
- Goでファイルをコピーするには、
io.Copy
、os.Open
、os.Create
を使用できます。 - 安全なファイル操作のためには、適切なエラー処理とリソースのクリーンアップ(
defer
経由)が不可欠です。 - パーミッションを保持するには、コピー後に
os.Stat
とos.Chmod
を使用します。
ファイルのコピーは、ログの書き込み、アップロードの処理、ローカルバックアップの管理など、多くのアプリケーションで一般的なタスクです。Go(Golang)では、標準ライブラリに、ファイルのコピーを含むファイル操作を処理するための強力かつ効率的な方法が用意されています。この記事では、慣用的なコードとベストプラクティスを使用して、Goでファイルをコピーする方法について説明します。
前提条件
始める前に、以下を確認してください。
- Goがインストールされていること(バージョン1.16以上を推奨)
- Goの構文に関する基本的な知識
- 動作するGo開発環境
io.Copy
を使用してファイルをコピーする
Goでファイルをコピーする最も簡単な方法は、標準ライブラリのio.Copy
関数を使用することです。完全な例を次に示します。
package main import ( "fmt" "io" "os" ) func copyFile(src, dst string) error { // ソースファイルを開く sourceFile, err := os.Open(src) if err != nil { return fmt.Errorf("ソースファイルのオープンに失敗しました: %w", err) } defer sourceFile.Close() // デスティネーションファイルを作成する destinationFile, err := os.Create(dst) if err != nil { return fmt.Errorf("デスティネーションファイルの作成に失敗しました: %w", err) } defer destinationFile.Close() // コンテンツをコピーする _, err = io.Copy(destinationFile, sourceFile) if err != nil { return fmt.Errorf("ファイルのコピーに失敗しました: %w", err) } // ファイルメタデータをディスクにフラッシュする err = destinationFile.Sync() if err != nil { return fmt.Errorf("デスティネーションファイルの同期に失敗しました: %w", err) } return nil } func main() { err := copyFile("example.txt", "copy.txt") if err != nil { fmt.Println("エラー:", err) } else { fmt.Println("ファイルが正常にコピーされました。") } }
説明
os.Open()
は、読み取りのためにソースファイルを開きます。os.Create()
は、デスティネーションファイルを作成(または切り捨て)します。io.Copy()
は、ソースからデスティネーションにデータを効率的に転送します。defer
は、ファイルハンドルが適切に閉じられるようにするために使用されます。Sync()
は、予期しないシャットダウンの場合にデータ損失のリスクを軽減するために、データがディスクにフラッシュされるようにします。
エラー処理
エラーをラップするためにfmt.Errorf
で%w
を使用していることに注意してください。これにより、後でerrors.Is()
またはerrors.As()
でエラーのアンラップが可能になります。これは、デバッグとエラートレースのために大規模なアプリケーションで特に役立ちます。
ボーナス:ファイル権限の保持
元のファイルの権限を保持する場合は、関数を少し拡張できます。
import "io/fs" // コピーと同期後: info, err := os.Stat(src) if err != nil { return fmt.Errorf("ソースファイルの情報の取得に失敗しました: %w", err) } err = os.Chmod(dst, info.Mode().Perm()) if err != nil { return fmt.Errorf("ファイル権限の設定に失敗しました: %w", err) }
結論
Goでのファイルのコピーは、標準ライブラリを使用すると簡単かつ効率的に行えます。CLIツール、Webサーバー、ファイル管理アプリケーションのいずれに取り組んでいる場合でも、ファイルI/Oを適切に実行する方法を理解することが不可欠です。
大規模なディレクトリのコピー、シンボリックリンクの処理、メタデータの保持など、より高度なユースケースでは、spf13/aferoのようなサードパーティライブラリを調べてみたり、カスタムの再帰的ロジックを作成したりすることもできます。
FAQs
io.Copy
は効率的で、内部でバッファリングされたI/Oを処理するため、コードがよりシンプルになり、高速になります。
デスティネーションファイルでfile.Sync()
を使用して、OSバッファをディスクにフラッシュします。
os.Stat()
を使用して元のモードを取得し、os.Chmod()
を使用して新しいファイルに適用します。
Leapcellは、Goプロジェクトをホストするための最適な選択肢です。
Leapcellは、Webホスティング、非同期タスク、およびRedisのための次世代サーバーレスプラットフォームです。
多言語サポート
- Node.js、Python、Go、またはRustで開発できます。
無制限のプロジェクトを無料でデプロイ
- 使用量に対してのみ支払いが発生し、リクエストや料金は発生しません。
比類のない費用対効果
- アイドル料金なしの従量課金制。
- 例:$25で平均応答時間60msで694万リクエストをサポートします。
合理化された開発者エクスペリエンス
- 簡単なセットアップのための直感的なUI。
- 完全に自動化されたCI/CDパイプラインとGitOpsの統合。
- 実用的な洞察を得るためのリアルタイムのメトリックとロギング。
簡単なスケーラビリティと高性能
- 高い同時実行性を容易に処理するための自動スケーリング。
- 運用上のオーバーヘッドはゼロで、構築に集中できます。
詳細については、ドキュメントをご覧ください。
Xでフォローしてください:@LeapcellHQ