首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Golang中的XML编码器并不会关闭所有流中的标记。

Golang中的XML编码器并不会关闭所有流中的标记。
EN

Stack Overflow用户
提问于 2019-11-26 09:25:03
回答 1查看 204关注 0票数 1

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

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

代码语言:javascript
复制
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时,我能期待同样的结果吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-26 09:50:36

在返回的io.PipeReader上不能有多个读取器,数据不会对所有读取器重复。io.PipeReader只能“为”一个读者提供服务,您可以启动2个goroutines来阅读它。

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

例如:

代码语言:javascript
复制
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)

这将输出(在围棋游乐场上尝试它):

代码语言:javascript
复制
<test><Point><X>1</X><Y>2</Y></Point></test>
<test><Point><X>1</X><Y>2</Y></Point></test>

上面的示例写入内存中的两个缓冲区.要写入2个文件,您可以将2个S传递给io.MultiWriter() (或其他实现io.Writer的东西):

代码语言:javascript
复制
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)

// ...
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59047594

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档