如何将大量数据封送到XML
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将大量数据封送到XML相关的知识,希望对你有一定的参考价值。
我需要通过XML发送大量数据,并且我的Docker容器在执行任务时耗尽内存。有没有办法使用Go逐步编组大型XML文档,并逐步将其写入文件,以最大限度地减少内存使用?
答案
使用xml.Encoder
将XML输出流式传输到可能是网络连接(io.Writer
)或文件(net.Conn
)的os.File
。完整的结果不会保留在内存中。
您可以使用Encoder.Encode()
将Go值编码为XML。通常,您可以传递任何传递给xml.Marshal()
的Go值。
Encoder.Encode()
只有在您想要编组的数据准备好在内存中时才有用,这对您来说可能是可行的,也可能是不可行的。例如。如果你想编组一个不能(或不应该)被读入内存的大型列表,这对你来说不是一种拯救。
如果输入数据也不能保存在内存中,那么您可以通过标记和元素构造XML输出。您可以使用Encoder.EncodeToken()
,它允许您编写结果XML文档的“部分”。
例如,如果要将大列表写入输出,则可以编写一个开始元素标记(例如<list>
),然后逐个编写列表元素(每个元素从数据库或文件中获取,或者由一个动态算法),一旦列表被封送,你可以关闭列表元素标签(</list>
)。
这是一个简单的例子,你可以这样做:
type Student struct {
ID int
Name string
}
func main() {
he := func(err error) {
if err != nil {
panic(err) // In your app, handle error properly
}
}
// For demo purposes we use an in-memory buffer,
// but this may be an os.File too.
buf := &bytes.Buffer{}
enc := xml.NewEncoder(buf)
enc.Indent("", " ")
he(enc.EncodeToken(xml.StartElement{Name: xml.Name{Local: "list"}}))
for i := 0; i < 3; i++ {
// Here you can fetch / construct the records
he(enc.Encode(Student{ID: i, Name: string(i + 'A')}))
}
he(enc.EncodeToken(xml.EndElement{Name: xml.Name{Local: "list"}}))
he(enc.Flush())
fmt.Println(buf.String())
}
上面的输出是(在Go Playground上试试):
<list>
<Student>
<ID>0</ID>
<Name>A</Name>
</Student>
<Student>
<ID>1</ID>
<Name>B</Name>
</Student>
<Student>
<ID>2</ID>
<Name>C</Name>
</Student>
</list>
以上是关于如何将大量数据封送到XML的主要内容,如果未能解决你的问题,请参考以下文章