英文:
Need io.ReaderAt from zip archive entry (the entry is a nested .xlsx file)
问题
让我先说明一下,我已经知道 Excel 2007 文件本身就是一个被重命名为 .xlsx 的 .zip 文件。
好的,既然你知道了这一点,现在来解决问题。我正在尝试从一个 .zip 归档文件中提取一个 Excel 2007 文件,而且全部在内存中进行。我不能(或者说,我真的不想)将整个归档文件提取到磁盘上,然后再从那里处理 .xlsx 文件。
问题在于我们读取 Excel 2007 文件的方法需要一个 ReadAt 方法(比如 io.ReaderAt 中定义的方法)。不幸的是,archive/zip 包只提供了一个 zip 文件条目 的接口,它只返回 io.ReadCloser。
有没有办法解决这个问题?再次强调,我希望全部在内存中完成,而不需要将数据刷新到磁盘上。
英文:
Let me preface this question with the fact that I already know that an excel 2007 file is itself a .zip file, renamed to .xlsx.
Ok, now that you know that here's the deal. I'm trying to extract an Excel 2007 file from within a .zip archive all in memory. I can't (rather, I really don't want to) extract the whole archive to disk and then work with the .xlsx file from there.
The problem is that our method of reading excel 2007 files requires a ReadAt method (such as what is defined by io.ReaderAt). Unfortunately, the archive/zip package exposes an interface for zip file entries that only gives back io.ReadCloser.
Is there any way to get around this situation? Again, I'd like to do this all in memory, without flushing to disk at all.
答案1
得分: 14
因为ZIP格式不允许在未解压整个文件的情况下实现ReadAt,所以你需要做的就是解压整个文件。
这并不意味着你必须将其保存到磁盘,而是可以将其解压到内存中,并使用bytes
包中的Reader
来处理:
// ReadAll从readCloser读取直到EOF,并将数据作为[]byte返回
b, err := ioutil.ReadAll(readCloser) // readCloser是来自zip包的
if err != nil {
panic(err)
}
// bytes.Reader实现了io.Reader、io.ReaderAt等,你所需要的一切!
readerAt := bytes.NewReader(b)
英文:
Because the ZIP format doesn't allow an implementation of ReadAt without first uncompressing the entire file, you will need to do exactly that.
That doesn't mean you must save it to disk, but instead you can decompress it to memory and work on it from there using Reader
in the bytes
package:
// ReadAll reads from readCloser until EOF and returns the data as a []byte
b, err := ioutil.ReadAll(readCloser) // The readCloser is the one from the zip-package
if err != nil {
panic(err)
}
// bytes.Reader implements io.Reader, io.ReaderAt, etc. All you need!
readerAt := bytes.NewReader(b)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论