1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[golang]改行コードを維持して、1行単位にファイルを読み書きする

Posted at

はじめに

数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言語は始めたばかりで分からないことばかりですが、不備や改善点などあればご指摘ください。

参考

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

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?