需要从zip归档条目中获取io.ReaderAt(该条目是一个嵌套的.xlsx文件)。

huangapple go评论91阅读模式
英文:

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)

huangapple
  • 本文由 发表于 2013年10月29日 02:20:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/19642245.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定