go - 如何将 io.Reader 拆分为具有相同行数的多个 io.Reader?
问题描述
我想在 Go 中做同样的事情,就像在这里问的那样。
我正在解析一个巨大的日志文件,我需要逐行解析它。在每一行上,我将行反序列化为一个结构。数据可能来自任何数据源(文件、网络等)。io.Reader
所以,我在我的函数中收到了一个。由于文件很大,我想将它拆分到许多 goroutine 中。
我可以使用io.Pipe
etc 轻松完成此操作。但是,我需要在不切割线条的情况下拆分文件,例如,将它们分成两半而不在中间切割它们。这样,每个 goroutine 可能会收到一个io.Reader
,然后它们可能会在文件的不同部分工作。
有时,我还需要发送io.MultiReader
到我的函数。在那种情况下,我会再次这样做。所以,它不一定是同一个文件(但大部分是)。
func scan(r io.Reader, pf ProcessFunc) {
// need to split `r` here if `r` is:
// r.(io.ReadSeeker)
// run goroutine #1 with 50% of the stream
// uses bufio.Scanner
// run goroutine #2 with 50% of the stream
// uses bufio.Scanner
// another goroutine is receiving the deserialized values
// and sends them to the ProcessFunc for processing further
// down the pipeline
}
假设数据是这样的:
foo1 bar2
foo3 bar4
foo5 bar6
foo7 bar8
goroutine #1 将获得一个 io.Reader ,如下所示:
foo1 bar2
foo3 bar4
goroutine #2 会得到一个 io.Reader ,如下所示:
foo5 bar6
foo7 bar8
但不是这样:
o5 bar6 -> breaks the line in the second io.Reader
foo7 bar8
解决方案
你有几个选择:
如果您有可搜索的数据,您可以搜索然后扫描下一个换行符,这样您就可以确保只在换行符处拆分
将行传递给 goroutine 而不是 io.readers。基本上,每个 goroutine 都会有一个通道,主路由会将 io.reader 中的每一行输入到通道中。
事先用类似的东西拆分文件
split