繁体   English   中英

如何使用rubyzip解压缩压缩文件夹

[英]How to unzip a zipped folder with rubyzip

我知道如何使用rubyzip检索普通zip文件的内容。 但是我解压缩拉链文件夹的内容时遇到了麻烦,我希望你们中的任何人都可以帮助我。

这是我用来解压缩的代码:

Zip::ZipFile::open(@file_location) do |zip|
 zip.each do |entry|
  next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/ or !entry.file?
  logger.debug "#{entry.name}"
  @data = File.new("#{Rails.root.to_s}/tmp/#{entry.name}")
 end
end

entry.name为我提供了zip文件中文件的名称。 这与普通的zipfile完美配合。 但是当从文件夹创建zipfile时,条目的名称类似于:test-folder / test.pdf。 当我然后尝试创建该文件时,它告诉我无法找到该文件。 这可能是因为它位于拉链内的“测试”文件夹内。

如果我将条目检查为文件夹,则无法找到任何文件夹。 所以我认为解决方案是将条目作为流读取,然后将其另存为文件。 很容易获得入门流,但如何将其保存为文件? 这是我到目前为止所得到的。

Zip::ZipFile::open(@file_location) do |zip|
 zip.each do |entry|
  next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/ or !entry.file?
  logger.debug "#{entry.name}"
  @data = entry.get_input_stream.read
  # How do i create a file from a stream?
 end
end

基本上我的问题是:如何从流创建文件? 还是比我的更方便?

===编辑===我用paperclip来存储文件。

我发现基于jhwist的更简单的方法工作正常:

Zip::File.open(@file_location) do |zipfile|
  zipfile.each do |entry|
    # The 'next if...' code can go here, though I didn't use it
    unless File.exist?(entry.name)
      FileUtils::mkdir_p(File.dirname(entry.name))
      zipfile.extract(entry, entry.name) 
    end
  end
end

条件显然是可选的,但如果没有它,代码会在尝试覆盖现有文件时引发错误。

我认为您的问题不在于您是否需要从流中编写文件。 基本上,如果你调用File.new它将创建一个新的IO-StreamFileIO的子类)。 因此,无论您想对zipfile中的流做什么,都应该使用常规文件。

当你说

当我然后尝试创建该文件时,它告诉我无法找到该文件

我想会发生的事情是您要创建的文件的父目录不存在(在您的情况下是test-folder )。 你想做的就是这样(未经测试):

Zip::ZipFile::open(@file_location) do |zip|
 zip.each do |entry|
   next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/ or !entry.file?
   logger.debug "#{entry.name}"
   FileUtils::mkdir_p(File.dirname(entry.name)) # might want to check if it already exists    
   @data = File.new("#{Rails.root.to_s}/tmp/#{entry.name}")
 end
end

我通过使用流并创建StringIO来解决它。 这是代码

Zip::ZipFile::open(@file_location) do |zip|
 zip.each do |entry|
  next if entry.name =~ /__MACOSX/ or entry.name =~ /\.DS_Store/ or !entry.file?

  begin
   # the normal unzip-code
  rescue Errno::ENOENT
   # when the entry can not be found
   @data = entry.get_input_stream.read
   @file = StringIO.new(@data)
   @file.class.class_eval { attr_accessor :original_filename, :content_type }
   @file.original_filename = entry.name
   @file.content_type = MIME::Types.type_for(entry.name)

   # save it / whatever
  end
 end
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM