Go中的复杂管道(第三部分)-将数据转换为制表符分隔的数值

57 阅读2分钟

将数据转换为制表符分隔的数值

第二部分中,我们重点讨论了持久化先前转换的数据,在这篇文章中,我们将致力于实现这一转换步骤。具体来说,我们将使用我们得到的数据,我们将确保以下游管道能够最简单地处理它的方式进行操作,这个组件是数据生产者过程的一个关键部分。

最低要求

与本帖相关的所有代码都在Github上,请自由探索以获得更多细节,以下是运行本例的最低要求。

  • Go 1.14

解析值

选择正确的包来解析数值取决于所使用的格式,这些格式的常见例子包括JSONCSVProtocol Buffers;了解正确的数据格式无疑是重要的,但了解所使用的具体标准和版本也很重要。

最终,要使用的包将由原始数据源决定。考虑到这一点,并回顾我们在第一部分中谈到的内容,我们可以肯定我们的原始数据源将是IMDB,具体文件是gzip的,包含tab分隔的数值。顺便说一下,在这篇文章中,我们不会涉及枪支压缩的部分,这将在以后的文章中讨论。

那么,这到底需要什么呢?

我们可以使用encoding/csv ,用类似的配置来设置我们的阅读器。

cr := csv.NewReader(br)
cr.Comma = '\t'
cr.LazyQuotes = true

然而这并不可行,原因是原始数据源并没有真正使用这个包所实现的预期格式。我明确地提到这一点,因为事先确定这一点真的很重要,它可能看起来像CSV(使用制表符而不是逗号),但实际上它不是。

实际上,解析IMDB的TSV文件的实现比这更容易。我们可以使用 bufio并做如下的事情。

br := bufio.NewReader(f)

for {
	line, err := br.ReadString('\n')
	if err == io.EOF {
		return
	}

	if err != nil {
		log.Fatalf("Reading TSV %s", err)
	}

	fmt.Printf("%#v\n", strings.Split(strings.Trim(line, "\n"), "\t"))
}

这应该会给我们带来我们所期望的东西:一个数据结构(在这种情况下是字符串的片断),可以很容易地被下游管道处理。

下一步是什么?

下一篇博文将介绍惊人的errgroup!我们就快把所有的东西连接在一起了。