【问题标题】:Reading files in a zip archive, without unzipping the archive读取 zip 存档中的文件,无需解压缩存档
【发布时间】:2022-03-31 05:15:09
【问题描述】:

我有一个包含 100 多个 zip 文件的目录,我需要读取 zip 文件中的文件以进行一些数据处理,而无需解压缩存档。

是否有一个 Ruby 库可以读取 zip 存档中的文件内容,而无需解压缩文件?

使用 ruby​​zip 会报错:

require 'zip'

Zip::File.open('my_zip.zip') do |zip_file|
  # Handle entries one by one
  zip_file.each do |entry|
    # Extract to file/directory/symlink
    puts "Extracting #{entry.name}"
    entry.extract('here')

    # Read into memory
    content = entry.get_input_stream.read
  end
end 

给出这个错误:

test.rb:12:in `block (2 levels) in <main>': undefined method `read' for Zip::NullInputStream:Module (NoMethodError)
    from .gem/ruby/gems/rubyzip-1.1.6/lib/zip/entry_set.rb:42:in `call'
    from .gem/ruby/gems/rubyzip-1.1.6/lib/zip/entry_set.rb:42:in `block in each'
    from .gem/ruby/gems/rubyzip-1.1.6/lib/zip/entry_set.rb:41:in `each'
    from .gem/ruby/gems/rubyzip-1.1.6/lib/zip/entry_set.rb:41:in `each'
    from .gem/ruby/gems/rubyzip-1.1.6/lib/zip/central_directory.rb:182:in `each'
    from test.rb:6:in `block in <main>'
    from .gem/ruby/gems/rubyzip-1.1.6/lib/zip/file.rb:99:in `open'
    from test.rb:4:in `<main>'

【问题讨论】:

  • github.com/rubyzip/rubyzip -> 滚动到“读取 Zip 文件”部分,您可以列出文件结构,您可以将文件读入内存 - 无需在文件系统上创建任何内容。
  • @sled 除了那个代码...实际上不起作用。

标签: ruby


【解决方案1】:

如果条目是目录而不是文件,则返回Zip::NullInputStream,是这样吗?

下面是更强大的代码变体:

#!/usr/bin/env ruby

require 'rubygems'
require 'zip'


Zip::File.open('my_zip.zip') do |zip_file|
  # Handle entries one by one
  zip_file.each do |entry|
    if entry.directory?
      puts "#{entry.name} is a folder!"
    elsif entry.symlink?
      puts "#{entry.name} is a symlink!"
    elsif entry.file?
      puts "#{entry.name} is a regular file!"

      # Read into memory
      entry.get_input_stream { |io| content = io.read }

      # Output
      puts content
    else
      puts "#{entry.name} is something unknown, oops!"
    end
  end
end

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,并在entry.get_input_stream.read 之前检查了if entry.file?,解决了这个问题。

    require 'zip'
    
    Zip::File.open('my_zip.zip') do |zip_file|
      # Handle entries one by one
      zip_file.each do |entry|
        # Extract to file/directory/symlink
        puts "Extracting #{entry.name}"
        entry.extract('here')
    
        # Read into memory
        if entry.file?
          content = entry.get_input_stream.read
        end
      end
    end 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-10
      • 2013-03-01
      • 2015-06-16
      • 2013-01-31
      • 2023-01-25
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      相关资源
      最近更新 更多