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

我正在开发一个流式 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 时,我能得到相同的结果吗?


泛舟湖上清波郎朗
浏览 89回答 1
1回答

牛魔王的故事

返回的数据上不能有多个读取器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.File(或io.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)// ...
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go