golang将struct写为原始数据

时间:2018-01-06 19:20:44

标签: linux go io low-level-io

我正在使用GO开发一种新型数据库。我想做的一件事就是拥有一个分布式磁盘,这样我就可以在多台机器上分发查询(想想Pi类型架构)。这意味着在原始磁盘上构建我自己的结构。

我的挑战是我找不到一个允许我从指向结构的指针写N个字节的GO包。所有IO包都限制了对[]字节切片的访问。

这对于保护是很好的,但是如果我必须通过某种形式的编码通过字节数组缓冲所有内容,那么它将减慢对特定对象的访问速度。

任何人都知道如何进行原始IO?或者我是否必须处理GOB作为我的IO单位并受到编码/解码的惩罚?

3 个答案:

答案 0 :(得分:3)

首先发出重大警告:不要这样做:既不安全也不便携

对于给定的结构,您可以反思它以找出实际结构的内存大小,然后使用[('good to see you...', 'John'), ('hi', 'Joe'), ('hey', 'John'), ('how are you?', 'Joe')] 将其安全地转换为[]byte

例如:unsafe

这将为您提供一些C-ish,绝对没有安全保证或便携性。

我引用Go spec

  

对于类型安全,必须手动审查使用不安全的包裹,并且可以   不可携带。

您可以在此Go and Memory layout帖子中找到更多详细信息,包括将结构不安全地视为字节所需的所有步骤。

总的来说,检查Go如何在低级别上运行很有吸引力,但在你的情况下这绝对是错误的。任何真正的数据基础设施都需要存储逻辑,而不仅仅是将内存中的结构转储到磁盘上。

答案 1 :(得分:1)

通常,您不能对Go结构(即memdump)执行原始IO。这是因为Go中的许多内容都包含指针,实际数据在内存中不是连续的。

例如,像这样的结构:

type Person struct {
    Name string
}

包含一个字符串,该字符串依次为字符串的字节contains a pointer。原始memdump只会转储指针。

解决方案是序列化。这绝不是免费的,尽管有些实现做得很好。

与您所描述的最接近的是go-memdump,但我不建议将其用于制作。

否则,我建议查看performant serialization technique。 (Go的gob编码不是最好的。)

答案 2 :(得分:0)

  

...或者我是否必须将GOB作为我的IO单位处理并受到编码/解码的惩罚?

只需使用GOB。 过早优化是万恶之源。