2

我有一些宝贵的代码压缩了大量文件,它在 tmp 文件系统中创建了一个 zip 文件,并在那里添加了文件。

我试图通过使用 ruby​​ 的 Tempfile 将文件存储在代码中来提高效率,而不是自己手动将其写入 tmp 目录并稍后将其删除。

我已经编写了这段代码来尝试这样做……</p>

def zip_up_files
  require 'zip/zip'

  t = Tempfile.new(["temp-filename-#{export_type}", '.zip'], :type => 'application/zip')
  Zip::ZipOutputStream.open(t.path) do |z|
    #pop some files in the zip...
  end

  #save it to the has_attachment :download on the model
  self.download = File.open(t.path)
  self.save

  #delete TempFile...
  t.close
end

这成功将 Tempfile 保存到模型上的 .download 中。但是,如果您现在导航到保存的 zip 文件,它不是一个 zip 文件,而是一个乱码文本文档。我想知道在将其保存到模型之前是否缺少创建或保存 zip 的内容。我尝试将类型放入创建的 TempFile 中。看起来 zip 缺少 MimeType。但我不确定,有人可以帮忙吗?

谢谢!

4

2 回答 2

5

问题是,您已将二进制文件写入磁盘,但随后您以文本模式而不是二进制模式打开它。这肯定会弄乱数据。

# Opens in text mode by default!
#self.download = File.open(t.path)

# Change to...
self.download = File.open(t.path, 'rb')

顺便说一句,close不会删除临时文件。当文件句柄被垃圾收集时,文件将被删除。建议unlink显式调用以删除临时文件,否则磁盘上将有大量临时文件等待垃圾收集。(请参阅TempFile 文档中的概要和良好实践。)

#delete TempFile...
t.close
t.unlink
于 2013-04-28T04:18:42.557 回答
1

我认为文件名没有正确生成

t = Tempfile.new(["temp-filename-#{export_type}", '.zip'], :type => 'application/zip')

在这条线之后你可以做

   p t.path 

并检查终端中的打印值

或者

你可以更新你的代码来匹配这个它对我来说很好

    require 'zip/zip'
    Zip::ZipFile.open("my.zip", Zip::ZipFile::CREATE) {
     |zipfile|
      #do some awesome staff
     }
于 2013-04-25T11:04:38.860 回答