Golang中的XML编码器不会关闭所有流中的标签

标签 xml go xml-encoding

我正在开发一个流式 XML 编码器,它将同时将 XML 写入本地文件和 S3 存储桶。然而,通过测试它写入两个本地文件,我可以看到其中一个文件每次都缺少结束标记。

以下是我的大致做法(省略错误处理):

func copyToFile (fileName string) {
    f, _ := os.Create(fileName)
    defer f.Close()
    io.Copy(f, pr)
}

func main () {
    pr, pw := io.Pipe()
    defer pw.Close()

    encoder := xml.NewEncoder(pw)

    go copyToFile("file1.xml")
    go copyToFile("file2.xml")

    encoder.EncodeToken(xml.StartElement{...})
    encoder.Encode(SomeStruct{})
    encoder.EncodeToken(xml.EndElement{...})
    encoder.Flush()
}

file1.xml 中的结果符合预期,所有标记都正确关闭,但在 file2.xml 中,结束标记(调用 encoder. EncodeToken(xml.EndElement{...})) 丢失。

我做错了什么?当我将阅读器复制到 S3 时,我可以获得相同的结果吗?

最佳答案

返回的 io.PipeReader 上不能有多个读者,不会为所有读者复制数据。 io.PipeReader 只能“服务”单个读取器,并且您启动 2 个 goroutine 来从中读取数据。

要实现您想要的效果,请使用 io.MultiWriter() 。它会返回一个 io.Writer到您可以写入的位置,它会将写入复制到您传递给它的所有写入器。

例如:

f1 := &bytes.Buffer{}
f2 := &bytes.Buffer{}

w := io.MultiWriter(f1, f2)

encoder := xml.NewEncoder(w)

encoder.EncodeToken(xml.StartElement{Name: xml.Name{Local: "test"}})
encoder.Encode(image.Point{1, 2})
encoder.EncodeToken(xml.EndElement{Name: xml.Name{Local: "test"}})
encoder.Flush()

fmt.Println(f1)
fmt.Println(f2)

这将输出(在 Go Playground 上尝试):

<test><Point><X>1</X><Y>2</Y></Point></test>
<test><Point><X>1</X><Y>2</Y></Point></test>

上面的示例写入 2 个内存缓冲区。要写入 2 个文件,您可以传递 2 os.Filesio.MultiWriter() (或任何其他实现 io.Writer):

f1, err := os.Create("file1.xml")
if err != nil {
    panic(err)
}
defer f1.Close()

f2, err := os.Create("file2.xml")
if err != nil {
    panic(err)
}
defer f2.Close()

w := io.MultiWriter(f1, f2)

// ...

关于Golang中的XML编码器不会关闭所有流中的标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59047594/

相关文章:

c# - XML序列化和生成HTML文档时的 "<"、 ">"

java - XSL 转换期间的 Unicode 字符

java - 具有多个父节点的 DocumentBuilderFactory

github - 如何使 godoc 链接到 github 上的源代码

session - 在 golang 中将 map、struct 设置为 session (gin gonic 框架)

java - 读/写保留原始属性顺序的 XML 文件

c# - 为什么覆盖 XML 文件会创建额外的结束标记?

go - 如何在 Go 中处理来自 Druid 查询的大型 http 响应体

Boost 读/写 XML 文件 : how to change the characters encoding?