Go/ファイル入出力
< Go
ファイル入出力
編集ファイルの作成・読出し・書込みなどの操作を「ファイル入出力」と言います。
Goのファイル入出力機能は、 "os" パッケージで実装されています。
"os" パッケージで定義された関数 os.Open
関数でファイルをオープンできます。
os.Open
関数を使用する際、この関数は戻り値を2つ返します(多値返却)。
os.Open
関数の第1戻値は正常動作時の戻値(*os.File)、第2戻値はエラー時に nil 以外を返します。
ファイルのオープンと読出し
編集バッファリングなし
編集- ファイルのオープンと読出し(バッファリングなし)
// Package main は、指定されたファイルを読み取り、標準出力に内容を表示するプログラムを提供します。 package main import ( "io" "log" "os" ) // main 関数は、/etc/hosts ファイルを開き、その内容を読み取って標準出力に書き出します。 // ファイル操作中にエラーが発生した場合、適切にログを出力してプログラムを終了します。 func main() { // /etc/hosts ファイルを開く f, err := os.Open("/etc/hosts") if err != nil { // ファイルを開けない場合、エラーメッセージを出力して終了 log.Fatal(err) } // ファイルを閉じる処理を defer に登録 defer f.Close() // ファイルを確実に閉じる // バッファを作成してデータを読み込む b := make([]byte, 4096) // 4KB のバッファ for { // ファイルから読み込む switch c, err := f.Read(b); { // 読み込んだバイト数が 0 の場合、終了 case c == 0: return // EOF (End of File) に達した場合、終了 case err == io.EOF: return // その他のエラーが発生した場合 case err != nil: log.Fatal(err) // 正常に読み込めた場合 case err == nil: // 読み込んだ内容を標準出力に書き込む os.Stdout.Write(b[:c]) // 想定外の状況 (冗長な安全策) default: panic("???") } } }
- 解説
os.Open
/etc/hosts
ファイルを読み込み専用で開きます。失敗時はエラーを処理。defer f.Close()
プログラム終了時に確実にファイルを閉じるための処理。make([]byte, 4096)
読み込みバッファを 4KB 確保。f.Read(b)
ファイルを読み込み、結果をバッファに格納。io.EOF
ファイルの終端に到達した場合の特別なエラーコード。log.Fatal
エラー発生時にログ出力し、即座にプログラムを終了。os.Stdout.Write
標準出力にバッファ内容を書き出す。
バッファリングあり
編集- ファイルのオープンと読出し(バッファリングあり)
// Package main は、指定されたファイルを読み取り、その内容を標準出力に表示するプログラムを提供します。 // バッファ付きリーダーを使ってファイルの内容を行単位で読み取ります。 package main import ( "bufio" "io" "log" "os" ) func main() { // /etc/hosts ファイルを開く file, err := os.Open("/etc/hosts") if err != nil { // ファイルを開けない場合、エラーメッセージを出力して終了 log.Fatal(err) } // ファイルを閉じる処理を defer に登録 defer file.Close() // ファイルを確実に閉じる // バッファ付きリーダーを作成 reader := bufio.NewReader(file) // ファイルの内容を一行ずつ読み込んで出力 for { // 改行文字で区切られたバイト列を読み込む if line, err := reader.ReadBytes('\n'); err != nil { // エラーが io.EOF の場合、ファイルの終わり if err == io.EOF { break // ファイルの終わりに達したのでループを終了 } // それ以外のエラーの場合、エラーログを出力して終了 log.Fatal(err) } else { // 読み込んだ行を標準出力に書き出す os.Stdout.Write(line) } } }
- 解説
os.Open
/etc/hosts
ファイルを開きます。失敗した場合、エラーメッセージをログに出力し、プログラムを終了します。defer file.Close()
プログラムが終了する際にファイルを閉じる処理を登録します。defer
は遅延実行されるため、ファイルのクローズを確実に行います。bufio.NewReader(file)
bufio.NewReader
を使用してバッファ付きリーダーを作成し、ファイルから効率よくデータを読み込みます。reader.ReadBytes('\n')
ReadBytes
は改行文字\n
までのバイト列を読み込みます。読み込んだデータはバイトスライスとして返されます。io.EOF
ファイルの終わりに達した場合に発生するエラーです。このエラーが発生した場合、ループを終了します。os.Stdout.Write(line)
標準出力に読み込んだ行をそのまま書き出します。
- 特徴
このコードは、ファイルからバッファを使って効率的にデータを読み込み、行単位で処理する方法を示しています。ReadBytes
を使うことで、改行ごとに分割されたバイト列を取得し、標準出力に書き出しています。
バッファリング
バッファリングは、複数の機器やプログラムの間でデータを転送する場合に、予め用意した記憶領域(バッファー)に送受信データを一時的に保存する手法で
- 処理速度や転送速度の差を補う
- 通信の減速や中断に備える
ことを目的としています。
バッファリングすることで、
- 動作速度の向上
- 入出力要求の回数の削減
- ジッターの防止あるいは低減
などが図れます。
バッファーにある未処理のデータを強制的に次の処理に送り出すことを、フラッシュ(flash)と呼びます。ファイルの作成と書込み
編集"os" パッケージで定義された関数 os.Create
関数でファイルを作成できます。
os.Create
関数を使用する際、この関数は戻り値を2つ返します(多値返却)。
os.Create
関数の第1戻値は正常動作時の戻値(*os.File)、第2戻値はエラー時に nil 以外を返します。
- ファイルの作成と書込み
// Package main は、新しいファイルを作成し、そこにテキストを書き込むプログラムを提供します。 // ファイル作成時や書き込み時にエラーが発生した場合、適切なエラーメッセージを出力します。 package main import ( "log" "os" ) func main() { // "file-create-test.txt" という名前の新しいファイルを作成 f, err := os.Create("file-create-test.txt") if err != nil { // ファイル作成に失敗した場合、エラーメッセージをログに出力して終了 log.Fatal(err) } // ファイルを閉じる処理を defer に登録 defer f.Close() // ファイルに文字列 "TEST TEXT\n" を書き込む if _, err := f.Write([]byte("TEST TEXT\n")); err != nil { // 書き込みに失敗した場合、エラーメッセージをログに出力して終了 log.Fatal(err) } }
- 解説
os.Create("file-create-test.txt")
os.Create
は指定されたファイル名で新しいファイルを作成します。もしファイルが既に存在する場合、上書きされます。ファイル作成に失敗した場合、エラーメッセージをログに出力し、プログラムを終了します。defer f.Close()
defer
を使用して、ファイルのクローズを遅延実行します。これにより、関数終了時に必ずファイルが閉じられます。f.Write([]byte("TEST TEXT\n"))
Write
メソッドを使用して、指定されたバイトスライス(ここでは "TEST TEXT\n")をファイルに書き込みます。書き込みに失敗した場合、エラーメッセージをログに出力し、プログラムを終了します。
- 特徴
このプログラムは、ファイルの作成から書き込み、そしてファイルのクローズ処理を行います。defer
を使ってファイルクローズ処理を遅延させることで、関数終了時に必ずファイルが閉じられることを保証しています。エラーが発生した場合は、log.Fatal
によって即座にエラーメッセージが出力され、プログラムは終了します。