当前位置 : 首页 > 购买指南

Go文件读取:os.ReadFile与bufio.Scanner详解

<|begin▁of▁sentence|>--- title: "Golang でファイルを読み込む (os.ReadFile, os.Open, bufio.Scanner)" linkTitle: "ファイルを読み込む (os.ReadFile, os.Open, bufio.Scanner)" url: "p/5qo6x5a/" date: "2022-09-09" tags: ["Go"] --- ファイル全体を一度に読み込む (os.ReadFile) ---- Go 1.16 で追加された [os.ReadFile 関数](https://pkg.go.dev/os#ReadFile) を使うと、ファイル全体を一度に読み込むことができます。 ファイルサイズが大きい場合は効率が悪くなりますが、小さなファイルを読み込むときはシンプルで分かりやすいです。 {{< code lang="go" title="main.go" >}} package main import ( "fmt" "log" "os" ) func main() { data, err := os.ReadFile("input.txt") if err != nil { log.Fatal(err) } fmt.Print(string(data)) } {{< /code >}} {{< code lang="txt" title="実行結果" >}} Hello World {{< /code >}} `os.ReadFile` 関数はファイルの内容を `[]byte` スライスとして返すので、文字列として扱いたい場合は `string(data)` のように変換する必要があります。 ファイルが存在しない場合などは `err` が非 nil になるので、エラーチェックを忘れないようにします。 ファイルを開いて少しずつ読み込む (os.Open + bufio.Scanner) ---- サイズの大きいファイルを読み込む場合は、ファイルを開いて (`os.Open`) 少しずつ読み込んでいくのが効率的です。 次の例では、[bufio.Scanner](https://pkg.go.dev/bufio#Scanner) を使ってテキストファイルを 1 行ずつ読み込んでいます。 {{< code lang="go" title="main.go" >}} package main import ( "bufio" "fmt" "log" "os" ) func main() { file, err := os.Open("input.txt") if err != nil { log.Fatal(err) } defer file.Close() scanner := bufio.NewScanner(file) for scanner.Scan() { fmt.Println(scanner.Text()) } if err := scanner.Err(); err != nil { log.Fatal(err) } } {{< /code >}} {{< code lang="txt" title="実行結果" >}} Hello World {{< /code >}} `os.Open` 関数でファイルを開き、関数を抜けるときに確実にファイルを閉じるために `defer file.Close()` を実行します。 `bufio.Scanner` は、デフォルトで 1 行ずつ読み込むように設定されているので、`for` ループと組み合わせることで行単位の処理を行えます。 `Scanner` が EOF に達すると `for` ループを抜けますが、その他の要因(ファイルが途中で読めなくなったなど)でエラーが発生した場合は、`scanner.Err()` でエラー内容を確認できます。 `bufio.Scanner` はデフォルトで 1 行ずつ読み込みますが、`Scanner#Split` メソッドで分割関数を変更することで、単語単位で読み込むこともできます。 ```go scanner := bufio.NewScanner(file) scanner.Split(bufio.ScanWords) // 単語単位で読み込む for scanner.Scan() { fmt.Println(scanner.Text()) } ``` その他の分割関数として、`bufio.ScanBytes` (バイト単位)、`bufio.ScanRunes` (ルーン単位) などがあります。

栏目列表