为什么 json.Encoder 多加一行?

json.Encoder似乎与json.Marshal. 具体来说,它在编码值的末尾添加了一个新行。知道这是为什么吗?对我来说这看起来像是一个错误。


package main


import "fmt"

import "encoding/json"

import "bytes"


func main() {

    var v string

    v = "hello"

    buf := bytes.NewBuffer(nil)

    json.NewEncoder(buf).Encode(v)

    b, _ := json.Marshal(&v)


    fmt.Printf("%q, %q", buf.Bytes(), b)

}

这输出


"\"hello\"\n", "\"hello\""


小唯快跑啊
浏览 457回答 3
3回答

忽然笑

因为他们在使用Encoder.Encode. 这是该函数的源代码,它实际上声明它在文档中添加了一个换行符(请参阅注释,这是文档):https://golang.org/src/encoding/json/stream.go?s=4272:4319// Encode writes the JSON encoding of v to the stream,// followed by a newline character.//// See the documentation for Marshal for details about the// conversion of Go values to JSON.func (enc *Encoder) Encode(v interface{}) error {    if enc.err != nil {        return enc.err    }    e := newEncodeState()    err := e.marshal(v)    if err != nil {        return err    }        // Terminate each value with a newline.    // This makes the output look a little nicer    // when debugging, and some kind of space    // is required if the encoded value was a number,    // so that the reader knows there aren't more    // digits coming.    e.WriteByte('\n')    if _, err = enc.w.Write(e.Bytes()); err != nil {        enc.err = err    }    encodeStatePool.Put(e)    return err}现在,除了“使输出看起来有点好”之外,Go 开发人员为什么要这样做?一个答案:流媒体go jsonEncoder针对流进行了优化(例如 json 数据的 MB/GB/PB)。通常,在流式传输时,您需要一种方法来确定流何时完成。在 的情况下Encoder.Encode(),这是一个\n换行符。当然,您当然可以写入缓冲区。但是你也可以写入一个 io.Writer ,它会流式传输v.这与json.Marshal如果您的输入来自不受信任(且未知受限)的来源(例如,对您的 Web 服务的 ajax POST 方法 - 如果有人发布 100MB json 文件怎么办?)的使用通常是不鼓励的。并且,json.Marshal将是最终完整的 json 集 - 例如,您不会期望将 100Marshal个条目连接在一起。您将使用 Encoder.Encode() 来构建一个大集合并写入缓冲区、流、文件、io.Writer 等。每当怀疑它是否是一个错误时,我总是查找源代码 - 这是 Go 的优势之一,它的源代码和编译器只是纯粹的 Go。在 [n]vim 中,我使用我的设置\gb在浏览器中打开源定义。.vimrc

隔江千里

您可以通过向后流擦除换行符:f, _ := os.OpenFile(fname, ...)encoder := json.NewEncoder(f)encoder.Encode(v)f.Seek(-1, 1)f.WriteString("other data ...")他们应该让用户控制这种奇怪的行为:禁用它的构建选项Encoder.SetEOF(eof 字符串)Encoder.SetIndent(前缀,缩进,eof 字符串)

holdtom

该编码器写入文件流。额外的空格终止流中的 JSON 文档。流读取器需要终止符。考虑一个包含以下 JSON 文档的流:1, 2, 3. 如果没有额外的空格,线路上的数据就是字节序列123。这是一个编号为 123 的 JSON 文档,而不是三个文档。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go