我希望在GO中将字符串数组转换为字节数组,以便将其写入磁盘.将字符串数组([]string)编码和解码为字节数组([]byte)的最佳解决方案是什么?

我在考虑迭代字符串数组两次,第一次是为了获得字节数组所需的实际大小,第二次是 for each 元素写入长度和实际字符串([]byte(str)).

解决方案必须能够以另一种方式将其转换;从[]byte转换为[]string.

推荐答案

让我们忽略这样一个事实,那就是这是暂时的.您首先需要一种序列化格式来将[]string编组到其中.

这里有很多 Select .您可以构建自己的库,也可以使用库.我将假设您不想构建自己的格式,并跳转到序列化格式GO支持.

在所有示例中,DATA是[]string,FP是您要读/写的文件.错误被忽略,请判断函数的返回以处理错误.

采空区

GOB是一种仅限GO的二进制格式.随着字符串数量的增加,它应该是相对高效的空间.

enc := gob.NewEncoder(fp)
enc.Encode(data)

阅读也很简单

var data []string
dec := gob.NewDecoder(fp)
dec.Decode(&data)

GOB很简单,而且切中要害.但是,该格式仅对其他GO代码可读.

JSON

接下来是json.JSON是一种几乎无处不在的格式.这种格式同样易于使用.

enc := json.NewEncoder(fp)
enc.Encode(data)

阅读:

var data []string
dec := json.NewDecoder(fp)
dec.Decode(&data)

XML

XML是另一种常见的格式.然而,它有相当高的开销,而且不容易使用.虽然可以像处理gob和json一样,但正确的xml需要一个根标记.在本例中,我们使用根标记"Strings",每个字符串都被包装在一个"S"标记中.

type Strings struct {
    S []string
}

enc := xml.NewEncoder(fp)
enc.Encode(Strings{data})

var x Strings
dec := xml.NewDecoder(fp)
dec.Decode(&x)
data := x.S

CSV

CSV与其他的不同.您有两个选项,使用一条记录(n行)或n条记录(1行).以下示例使用n条记录.如果我用一张唱片会很无聊.它看起来太像其他的了.CSV只能保留字符串.

enc := csv.NewWriter(fp)
for _, v := range data {
    enc.Write([]string{v})
}
enc.Flush()

阅读:

var err error
var data string
dec := csv.NewReader(fp)
for err == nil {        // reading ends when an error is reached (perhaps io.EOF)
    var s []string

    s, err = dec.Read()
    if len(s) > 0 {
        data = append(data, s[0])
    }
}

你使用哪种格式取决于你的喜好.还有许多其他可能的编码我没有提到.例如,有一个名为bencode的外部库.我个人不喜欢bencode,但它很管用.这与bittorrent元数据文件使用的编码相同.

如果您想要进行自己的编码,那么编码/二进制是一个很好的起点.这将允许您尽可能地创建最紧凑的文件,但是我不认为这是值得的.

Go相关问答推荐

在字符串与字符串子切片上使用len进行位转移产生意外输出

使用Gorm创建自定义连接表

如何使用Docker Compose配置Go,使main. go文件位于/CMD文件夹中

Go在使用HTTP代理时如何处理DNS请求?

GoLang:无法发送带有附件的邮箱

如何在Golang中获取mp3文件的持续时间?

GO:如何指定类型约束,使S方法的参数类型与接收方的参数类型相同

从使用Golang otelmux检测的Otel跟踪中获取trace_id

nixOS 上的 Nginx 反向代理在try 加载 css/js 时返回 404

Go-如何在递归函数中关闭通道

Golang:如何在不转义每个动作的情况下呈现模板的模板?

如何仅提取时间作为持续时间

grpc-gateway:重定向与定义不匹配(原始文件)

Golang invopop jsonschema 使用 if/then/else

Golang 工作池实现意外工作

如果服务器在客户端的 gRPC 中不可用,则等待的方法

如何在 GORM 中获取字段值

显示作为服务帐户身份验证的谷歌日历事件 - Golang App

当 git clone 工作时,Go mod tidy 在私有存储库上失败

Golang 泛型同时具有接口和实现