📂

GO言語 ファイル書き込み後の読み込み方法[忘備録]

2024/12/19に公開

初めに

GOのosパッケージでのファイル操作で躓いたところの忘備録です。

問題

package main

import (
	"fmt"
	"log"
	"os"
)

func main() {
	// 一時ファイルの作成
	tempFile, err := os.CreateTemp("./", "*")
	if err != nil {
		log.Fatal(err)
	}
	defer os.Remove(tempFile.Name())

	// 一時ファイルへの書き込み
	if _, err := fmt.Fprint(tempFile, "Hello,world!"); err != nil {
		log.Println(err)
		return
	}

	data := make([]byte, 1024)

	// 一時ファイルの読み込み
	n, err := tempFile.Read(data)
	if err != nil {
		log.Println(err)
		return
	}
	// 読み込み結果表示
	log.Println(string(data[:n]))
}

実行結果↓

2024/12/18 13:07:03 EOF

このようなコードがあった場合、実行結果は一時ファイルの読み込みでエラーとなります。
理由はログの通りで、一時ファイルへの書き込み時にファイルポインタが末尾まで移動するので、そのまま読み込もうとするとファイルの末尾から読み込むことになります。

解決方法

Seekメソッドを使ってファイルポインタの位置を指定しましょう!
(修正後コード)

package main

import (
	"fmt"
	"log"
	"os"
)

func main() {
	// 一時ファイルの作成
	tempFile, err := os.CreateTemp("./", "*")
	if err != nil {
		log.Fatal(err)
	}
	defer os.Remove(tempFile.Name())

	// 一時ファイルへの書き込み
	if _, err := fmt.Fprint(tempFile, "Hello,world!"); err != nil {
		log.Println(err)
		return
	}

	// ファイルポインタの位置を移動
	if _, err = tempFile.Seek(0, 0); err != nil {
		log.Println(err)
		return
	}

	data := make([]byte, 1024)

	// 一時ファイルの読み込み
	n, err := tempFile.Read(data)
	if err != nil {
		log.Println(err)
		return
	}
	// 読み込み結果表示
	log.Println(string(data[:n]))
}

実行結果↓

2024/12/18 13:13:36 Hello,world!

Discussion