如何在Go中编辑阅读器

时间:2015-08-06 12:59:28

标签: go

我试图弄清楚在没有ioutil.ReadAll的情况下更改流中的某些数据的最佳做法。

我需要删除以某个字符开头的行并删除另一个字符的所有实例。

package main

import (
    "bufio"
    "bytes"
    "fmt"
    "os"

    "gopkg.in/pg.v3"
)

func main() {
    fieldSep := "\x01"
    badChar := "\x02"
    comment := "#"
    dbName := "foo"
    db := pg.Connect(&pg.Options{})

    file, err := os.Open("/path/to/file")
    if err != nil {
        fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
    }
    defer file.Close()

    // I need to iterate my file Reader here
    // all lines that begin with comment and remove them
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        file := bytes.TrimRight(file, comment)
    }
    // all instances of badChar should be dropped
    file := bytes.Trim(file, badChar)

    _, err = db.CopyFrom(file, fmt.Sprintf("COPY %s FROM STDIN WITH DELIMITER e'%s'", dbName, fieldSep))
    if err != nil {
        fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
    }

    err = db.Close()
    if err != nil {
        fmt.Fprintf(os.Stderr, "ERROR: %s\n", err)
    }
    fmt.Println("Import Done")
}

上下文:

我将大量(> 10GB)数据导入数据库,它分布在多个文件中。

我的数据库接口accepts a reader用于加载数据。

数据有非标准的行结尾,我需要删除评论(因为PG' COPY FROM并不好玩。)

我知道我编辑流的代码很糟糕,我只是找不到好的参考 - 谢谢!

1 个答案:

答案 0 :(得分:1)

如果我在你的位置,我会制作自己的Reader,并将其插入源和目的地之间。这就是一致的接口。您的读者可以轻松处理数据流过的小块数据。

Source (io.Reader)   ==>  Your filter (io.Reader) ==>  Destination (expects an io.Reader)
provides the data         does the transformations       rock'n'rolls

这样一个读卡器的库示例,它被插入读卡器和它的客户端之间bufio.Reader,它可以让你通过缓冲更大的源调用来加速许多类型的读卡器,并让它如果喜欢的话,客户端会以小比特消费数据。您可以查看其来源:http://golang.org/src/bufio/bufio.go