ファイルから一行ずつ、というのは割と探し出せるのですが、1バイトずつとか1文字ずつの処理をしたほうが便利かも、と思うことがありますので、防備録がてら書いておきます。

広告

結論: bufioがとても便利

結局のところ、golangではほぼbufio一択です。1バイトずつの場合はReadByte、1文字ずつの場合はReadRuneを使えばよいという感じ。
たとえばReadByteでいえば、

f,_ := os.Open(filepath)
defer f.Close()
br := bufio.NewReader(f)
loop := true
for loop {
    b, err := br.ReadByte()
    //何らかの処理
    if err != nil{
        loop = false
    }
}

といった感じで、1バイトずつ読み込んでいろいろできるようです。ReadRune()も、読みだされるのがrune、つまりUTF-8における1文字単位(読みだせなかった場合はUnicode.ReplacementChar、要するにコードポイントが正しくなかったことを示す文字が返ります)なだけでほぼ同じ。
なお返されるErrorは、ReadByteの場合はファイルの終わりか読み込みエラー、ReadRuneの場合はファイルの終わりか読み込みエラーです。

その他の方法

 現状bufioが一番手軽で、しかもバッファリングもしてくれるので便利なのですが、メモリに余裕があるためバッファリングは特に考えないなど、何らかのために使わない場合は、一応ほかに方法もあります。

全部読みだしてstring型かbyte配列にして処理

 見出しの通りです。ioutil.ReadAll等を用いてファイル内容を読み込んでしまい、いろいろとコード上で変換できるstring型かbyte配列に変換する方法です。
 string型にした場合、1バイトずつならstr[i]のような形でfor文を使ってiをインクリメントし、1文字ずつならfor range構文で取得したstring型をrangeの元にして変数を回せばOKです。
 byte配列にした場合、1バイトずつなら配列をfor文を使って参照していけばいいのでstring型より簡単かもしれません。1文字ずつはDecodeRuneを挟むので、byte配列からは難しいかも。
 この方法は、メモリに余裕がある前提になるかとは思いますが、慣れている人には便利だと思います。

Readメソッドで何とかする

 bufioにせず、io.Readerの要件になるReadメソッドでどうにかすることも可能です。
 たとえば1バイトずつだと長さ1の配列pを用意してn, err := r.Read(p)とか。
 ただ、Readメソッド自体けして簡単とはいえませんし、1文字ずつ読みだす場合は独自で処理を実装することになると思うので、関数が最初から備わっているbufioを使ったほうが、やっぱりいいと思います。

その他コメントなど

 とりあえずbufioにつっこんでいけばいろんな問題がだいぶ解決することってそれなりに多いと思うのですが、今回もそのパターンになりました。bufioてらべんり。

広告

関連コンテンツと広告

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA