如何在ruby中创建没有临时文件的zip文件?

时间:2014-05-30 14:38:27

标签: ruby zip temporary-files

我创建了一个包含一些生成内容的zip文件(换句话说:存档中的文件不存在,内容在我的脚本中构建)。

我使用类似的脚本:

#~ gem 'rubyzip', '=1.1.0'
require 'zip/zip'

zipname = 'test.zip'
File.delete(zipname) if File.exists?(zipname) #delete previous version

Zip::ZipFile.open(zipname, Zip::ZipFile::CREATE) do |zipfile|
  1.upto(100) do |i| #Just some testfiles with content
    zipfile.get_output_stream("%08i.txt" % i) do |output_entry_stream| #Filename
          output_entry_stream.write("Testcontent %08i" % i)            #generated content
        end
      sleep 1  #sleep some time to see the temporary files
  end   #testdocs
end #ZipFile.open(zipname)

这很好用,我的拉链里面有正确的数据。

但是在创建zip时我有很多临时文件。拉链完成时会删除它们,但文件在创建过程中会打扰我。如果该过程引发异常,那么我必须手动删除它们。

我对Zip :: VERSION 2.0.2和1.1.0(使用gem ruby​​zip)有这种行为

  • 我可以避免使用此临时文件吗?
  • 如果不是:我可以为他们确定(临时)文件夹吗?

2 个答案:

答案 0 :(得分:11)

请参阅“How can I generate zip file without saving to the disk with Ruby?

的答案

我调整了你的例子以证明它有效。

require 'zip/zip'

zipname = 'test.zip'
File.delete(zipname) if File.exists?(zipname) #delete previous version

stringio = Zip::ZipOutputStream::write_buffer do |zio|
  1.upto(5) do |i| #Just some testfiles with content
    zio.put_next_entry("test#{i}.txt") #Filename
    zio.write("Testcontent %08i" % i)  #generated content
    sleep 1 #sleep some time to see the temporary files
  end
end
stringio.rewind #reposition buffer pointer to the beginning
File.new("test.zip","wb").write(stringio.sysread) #write buffer to zipfile

答案 1 :(得分:5)

你需要兼容zip,还是gzip足够? Ruby附带the Zlib module,这样可以分别使用Zlib::GzipWriterZlib::GzipWriter轻松读取/写入gzip压缩文件:

require 'zlib'
Zlib::GzipWriter.open('foobar.gz') do |fo|
  fo.write "how now brown cow\n"
end

在命令行:

$file foobar.gz
foobar.gz: gzip compressed data, from Unix, last modified: Fri May 30 08:56:58 2014
$gunzip foobar.gz
$cat foobar
how now brown cow

如果您需要创建包含多个文件的存档,Ruby的Archive::Tar类可以提供帮助。 tar.gz文件小于等效的.zip文件according to Wikipedia,因为Zip和tar的方式不同 - > gZip work。

在tar或压缩文件时,要非常小心地尝试在内存中缓冲。在开发中测试很容易,因为我们很少使用全尺寸文件,但是一旦代码命中生产,并且文件大小膨胀到天文尺寸,突然间你的系统会遇到内存紧缩。我们经常处理GB范围内的文件,并且尝试压缩内存中的文件会使应用程序成为生产服务器上的坏公民。 不喜欢深夜接听电话只是为了听到我写的东西导致问题,所以要保守一点,确保你的应用程序可以毫无失败地处理它的任务。