m_shige1979のときどきITブログ

プログラムの勉強をしながら学習したことや経験したことをぼそぼそと書いていきます

Github(変なおっさんの顔でるので気をつけてね)

https://github.com/mshige1979

go言語の学習メモ5(ファイル処理)

go言語でファイル処理

fopenはないかも…
これが私の最初のファイル読み込みなんであって欲しかったけど…

テストデータ

aaa.txt
aaaa
vvvv
dddd
eeee

基本

sample1.go
package main

import (
	"fmt"
	"os"
)

func main(){

	fmt.Println("start")

	// ファイルを開いてパラメータチェック
	fp, err := os.Open("aaa.txt")
	if(err != nil){
		panic(err)
	}

	// ファイルを閉じる
	// deferは完了時に実行する
	defer fp.Close()

	// ファイルを読み込み
	buf := make([]byte, 256)
	for {
		c, _ := fp.Read(buf)
		if c == 0 {
			break
		}
		fmt.Println(buf)
	}

	fmt.Println("end")

}

$ go run sample_file1.go 
start
[97 97 97 97 10 118 118 118 118 10 100 100 100 100 10 101 101 101 101 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
end
$ 

なんとなくやったことはわかる。
なんかc言語のようにバイト配列を用意してどうこうしたということ。
バイトデータとして処理する場合はこれでいいのですが、行単位などの制御を行う場合はちょっと面倒かもしれない
もっと簡単な方法がほしい

bufioを使用する

sample2.go
package main

import (
	"fmt"
	"os"
	"bufio"
	"io"
)

func main(){

	fmt.Println("start")

	// ファイルを開いてパラメータチェック
	fp, err := os.Open("aaa.txt")
	if(err != nil){
		panic(err)
	}

	// ファイルを閉じる
	// deferは完了時に実行する
	defer fp.Close()

	// ファイルを読み込み
	reader := bufio.NewReaderSize(fp, 4096)
	for {
		// 改行コードで読み込み
		line, _, err := reader.ReadLine()
		if err == io.EOF {
			break
		}

		// trimして出力
		fmt.Println(string(line))
	}

	fmt.Println("end")

}

$ go run sample_file2.go 
start
aaaa
vvvv
dddd
eeee
end
$

ファイル書き込み

sample3.go
package main

import (
	"fmt"
	"os"
	"bufio"
)

func main(){

	fmt.Println("start")

	// ファイルを開いてパラメータチェック
	fp, err := os.OpenFile("/tmp/bbb.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
	if(err != nil){
		panic(err)
	}

	// ファルを書き込み
	writer := bufio.NewWriterSize(fp, 4096)
	writer.WriteString("aaaa\n")
	writer.Flush()

	writer.WriteString("bbbb\n")
	writer.Flush()

	writer.WriteString("cccc\n")
	writer.Flush()

	// ファイルを閉じる
	fp.Close()

	fmt.Println("end")

}

]$ go run sample_file3.go 
start
end
$ cat /tmp/bbb.txt 
aaaa
bbbb
cccc
$

※実はvagrantで実行した際、共用ディレクトリの場合なんかへんなロックがかかってパーミッションエラーで上書き不可になってしまったのでtmpへきゅうきょ差し替えした
※データとしては出力出来ている感じ…

参考

bufio - The Go Programming Language


Go でファイルを1行ずつ読み込む(csv ファイルも) - Qiita

所感

サンプルを作成しながら少しずつパッケージや関数の使い方を理解している。
すぐに理解できないのは仕方ないけどなるべく早く覚えたいので時間がほしいと思ってしまう。