7

open我有一个 ruby​​ 脚本,它使用 ruby​​s命令从服务器下载远程 ZIP 文件。当我查看下载的内容时,它会显示如下内容:

PK\x03\x04\x14\x00\b\x00\b\x00\x9B\x84PG\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x10\x00foobar.txtUX\f\x00\x86\v!V\x85\v!V\xF6\x01\x14\x00K\xCB\xCFOJ,RH\x03S\\\x00PK\a\b\xC1\xC0\x1F\xE8\f\x00\x00\x00\x0E\x00\x00\x00PK\x01\x02\x15\x03\x14\x00\b\x00\b\x00\x9B\x84PG\xC1\xC0\x1F\xE8\f\x00\x00\x00\x0E\x00\x00\x00\n\x00\f\x00\x00\x00\x00\x00\x00\x00\x00@\xA4\x81\x00\x00\x00\x00foobar.txtUX\b\x00\x86\v!V\x85\v!VPK\x05\x06\x00\x00\x00\x00\x01\x00\x01\x00D\x00\x00\x00T\x00\x00\x00\x00\x00

我尝试使用 Rubyzip gem ( https://github.com/rubyzip/rubyzip ) 以及它的类Zip::ZipInputStream,如下所示:

stream = open("http://localhost:3000/foobar.zip").read # this outputs the zip content from above
zip = Zip::ZipInputStream.new stream

不幸的是,这会引发错误:

 Failure/Error: zip = Zip::ZipInputStream.new stream
 ArgumentError:
   string contains null byte

我的问题是:

  1. 一般来说,是否可以下载 ZIP 文件并将其内容提取到内存中?
  2. Rubyzip 是适合它的库吗?
  3. 如果是这样,我该如何提取内容?
4

2 回答 2

11

我自己找到了解决方案,然后在stackoverflow:D(如何在Ruby中遍历内存中的zip文件

input = HTTParty.get("http://example.com/somedata.zip").body
Zip::InputStream.open(StringIO.new(input)) do |io|
  while entry = io.get_next_entry
    puts entry.name
    parse_zip_content io.read
  end
end
  1. 下载你的 ZIP 文件,我正在使用 HTTParty(但你也可以使用 ruby​​ 的open命令(require 'open-uri')。
  2. 使用将其转换为StringIOStringIO.new(input)
  3. io.get_next_entry使用(它返回一个实例Entry)遍历 ZIP 存档中的每个条目
  4. io.read您一起获得内容,并与entry.name您一起获得文件名。
于 2015-10-16T15:48:09.090 回答
7

就像我在https://stackoverflow.com/a/43303222/4196440中评论的那样,我们可以使用Zip::File.open_buffer

require 'open-uri'

content = open('http://localhost:3000/foobar.zip')

Zip::File.open_buffer(content) do |zip|
  zip.each do |entry|
    puts entry.name
    # Do whatever you want with the content files.
  end
end
于 2017-04-09T05:04:59.170 回答