はじめに
数GB単位の様々なテキストファイルをちょっとだけ置換したファイルを作る必要があり、最近勉強をはじめたGo言語で実装しようと思ったところ、色々混乱してしまったので、備忘録がてらここに記載します。
ソース
main
package main
import (
"bufio"
"io"
"log"
"os"
)
func main() {
// 入力ファイルの指定
srcFile, err := os.Open("./file1.txt")
if err != nil { log.Fatal(err) }
defer srcFile.Close()
// 出力ファイルの指定
dstFile, err := os.Create(".file2.txt")
if err != nil { log.Fatal(err) }
defer dstFile.Close()
r := bufio.NewReader(srcFile)
w := bufio.NewWriter(dstFile)
for {
row, err := r.ReadString('\n') // LF(\n)まで読み込み。結果、CRLF(\r\n)でも問題なし
if err != nil && err != io.EOF { log.Fatal(err) }
if err == io.EOF && len(row) == 0 { break } // 最終行に改行が無い場合を考慮し、len(row) == 0を入れる
// ここに加工処理を書く
// row = strings.Replace(row, "hogehoge1", "hogehoge2", -1) など
// 出力ファイルに書き込み
_, err = w.WriteString(row)
if err != nil { log.Fatal(err) }
}
err = w.Flush()
if err != nil { log.Fatal(err) }
}
解説
Go言語におけるファイルや標準入出力にはbufioパッケージが良いとのこと。
bufioには、bufio.readline()や、bufio.Scan()など、一行単位に読み込みするためのメソッドがあるのですが、これらは改行コードがトリムされるので私の目的には合致せず。
bufio.ReadString('\n')を使うとLF('\n')が登場するまで読み込みを行うため、CRLF('\r\n')でもLF('\n')でも想定通りの挙動をします。CR('\r')だけのファイルを扱うことはないので無視・・。
最後に
普段はPython書いてます。Go言語は始めたばかりで分からないことばかりですが、不備や改善点などあればご指摘ください。