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.Opento open a file - but this returns anfs.Filewhich 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.Files searching for the file name I want. Then thezip.Reader.Filedoes have an easy way to read it, callingOpenand 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)
}
}
}