Hi I am new to Go and want to read a struct from an XML file in a zip archive. I am having trouble fitting the pieces together - I can get something to work but it feels like there should be a more straightforward way.
To start I believe I need to use zip.OpenReader
to get a zip.ReadCloser
. At the end I need to have some []byte
to pass to xml.Unmarshall
.
In the middle I had two thoughts:
- Use
zip.ReadCloser.Open
to open a file - but this returns anfs.File
which doesn’t have an easy way to read its entire contents as bytes, that I can see. Also this seems to need to copy the bytes which is not needed, because the zip file is already decompressed in memory. - Iterate through the
zip.ReadCloser.File
s searching for the file name I want. Then thezip.Reader.File
does have an easy way to read it, callingOpen
and thenio.ReadAll
. But it seems unfortunate I need to do a linear iteration of the files myself.
So I am just looking for comments really, is there a smarter way to do this that I haven’t spotted?
Thanks in advance.
Here is some code, I know I’ve skipped all the error handling and defer
close stuff for simplicity.
func one() {
// var r *zip.ReadCloser
r, _ := zip.OpenReader("na.zip")
// var f fs.File
f, _ := r.Open("custom.xml")
// var bytes []byte
// ** Any way to avoid implementing this function myself?
bytes, _ := readfsfile(f)
// var custom Custom
custom := Custom{}
xml.Unmarshal(bytes, &custom)
fmt.Println(custom)
}
func two() {
// var r *zip.ReadCloser
r, _ := zip.OpenReader("na.zip")
// var file zip.Reader.File
// ** Any way to avoid this iteration?
for _, file := range r.File {
if file.Name == "custom.xml" {
// var reader io.ReadCloser
reader, _ := file.Open()
// var bytes []byte
bytes, _ := io.ReadAll(reader)
// var custom Custom
custom := Custom{}
xml.Unmarshal(bytes, &custom)
fmt.Println(custom)
}
}
}