Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
129
Help us understand the problem. What is going on with this article?
@ikawaha

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

More than 3 years have passed since last update.

概要

ファイルを読み込んで処理することがよくあるので忘備用のメモです.

ファイルを1行ずつ読み込む

bufio.Readerで読み込む

ReadString

引数にファイルが指定されていれば,ファイルをオープンして1行ずつ読み込みます.
引数が指定されていなければ,標準入力から1行ずつ読み込みます.

追記:ReadString('\n')で読み込むとWindowsの場合\rが残ってしまうのでReadLineの方がいいとのコメントいただきましたので,ReadLine使った版も載せておきました.

os.EOFでなくてio.EOFなのがはまりどころでした.

Readerはファイルをクローズすれば閉じられるみたいです.

package main

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

func main() {
        var fp *os.File
        var err error

        if len(os.Args) < 2 {
                fp = os.Stdin
        } else {
                fmt.Printf(">> read file: %s\n", os.Args[1])
                fp, err = os.Open(os.Args[1])
                if err != nil {
                        panic(err)
                }
                defer fp.Close()
        }

        reader := bufio.NewReaderSize(fp, 4096)
        for line := ""; err == nil; line, err = reader.ReadString('\n') {
                fmt.Print(line)
        }
        if err != io.EOF {
                panic(err)
        }
}

ReadLine

コメントいただいたので修正版.

package main

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

func main() {
        var fp *os.File
        var err error

        if len(os.Args) < 2 {
                fp = os.Stdin
        } else {
                fmt.Printf(">> read file: %s\n", os.Args[1])
                fp, err = os.Open(os.Args[1])
                if err != nil {
                        panic(err)
                }
                defer fp.Close()
        }

        reader := bufio.NewReaderSize(fp, 4096)
        for {
                line, _, err := reader.ReadLine()
                fmt.Println(string(line))
                if err == io.EOF {
                        break
                } else if err != nil {
                        panic(err)
                }
        }
}

bufio.Scannerで読み込む (推奨)

面倒だなとおもったらbufioにScanner という便利なものがありました.
http://golang.org/pkg/bufio/#example_Scanner_lines
サンプルを参考に,上の例と同じにするとこんな感じでしょうか.

package main

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

func main() {
        var fp *os.File
        var err error

        if len(os.Args) < 2 {
                fp  = os.Stdin
        } else {
                fp, err = os.Open(os.Args[1])
                if err != nil {
                   panic(err)
                }
                defer fp.Close()
        }

        scanner := bufio.NewScanner(fp)
        for scanner.Scan() {
            fmt.Println(scanner.Text())
        }
        if err := scanner.Err(); err != nil {
            panic(err)
        }
}

csv(tsv)形式のファイルの読み込み

csv形式のファイルを読み込むReaderが用意されているのでこれを使えば簡単.
区切り文字の指定をReader.Commaに設定するのがなんか気持ち悪いですが・・・.
下記はタブ区切りのファイルを読む場合のサンプルです.

package main

import (
        "encoding/csv"
        "fmt"
        "io"
        "os"
)

func main() {

        var fp *os.File
        if len(os.Args) < 2 {
                fp = os.Stdin
        } else {
                var err error
                fp, err = os.Open(os.Args[1])
                if err != nil {
                        panic(err)
                }
                defer fp.Close()
        }

        reader := csv.NewReader(fp)
        reader.Comma = '\t'
        reader.LazyQuotes = true // ダブルクオートを厳密にチェックしない!
        for {
                record, err := reader.Read()
                if err == io.EOF {
                        break
                } else if err != nil {
                        panic(err)
                }
                fmt.Println(record)
        }
}
129
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ikawaha

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
129
Help us understand the problem. What is going on with this article?