【问题标题】:Ruby auto deleting temp file?Ruby自动删除临时文件?
【发布时间】:2015-09-23 03:00:34
【问题描述】:

我很困惑。这是我的代码:

require 'csv'                                                               
require 'tempfile'                                                          

f = Tempfile.new('csv','/tmp')                                                 
f.write 'just wanna test'                                                       
f.close                                                                        

p f.path 

如果我打开输出路径,它是空的。

我认为这是因为每次 ruby​​ 会话退出时 TempFile 都会自动从文件系统中删除。但是,我怎么知道文件何时被删除?因为我想用它在我的 Rails 应用程序中创建临时文件,所以我担心文件在使用之前被删除了。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    来自文档:

    当 Tempfile 对象被垃圾回收时,或当 Ruby 解释器退出时,其关联的临时文件会被自动删除。

    因此,只要您的f 在范围内,它就不会被删除。如果退出 Ruby,它将被删除。如果您仍在 Ruby 中,但 f 已超出范围,则它是不确定的(可能未删除,但不保证存在,不应使用。)

    【讨论】:

    • 对不起,我没有看到你的答案...如果我看过的话,可以节省我写作的时间。
    • @Myst:别担心,我想我们之间的距离是 5-10 秒。
    【解决方案2】:

    当我创建许多要压缩的临时文件时,我看到Tempfile 在同一进程中被垃圾收集。在下面的代码中,如果我没有将Tempfile 句柄存储在handles 数组中,我会在Zip::File.open 块关闭时收到运行时错误(Errno::ENOENT: No such file or directory @ rb_sysopen):

    handles = []
    Zip::File.open(zip_file.path, Zip::File::CREATE) do |zip|
      # there are hundreds of @foos to iterate over
      @foos.each do |foo|
        cit_filename = generate_some_unique_filename
        cit_file = Tempfile.new(cit_filename)
        handles << cit_file
        cit_file.puts('some text')
        cit_file.close
        zip.add(cit_filename, cit_file.path)
      end
    end # <- runtime error would have thrown at this point
    handles = nil
    

    【讨论】:

    • 哇,这真的很酷。你刚刚拯救了我的一天。在找到您的解决方案之前,我一直遇到与您完全相同的问题。
    • 我将 tempfile 对象放入哈希中以防止 GC。我从来没有访问过散列内的对象,但散列本身被访问并且没有被垃圾收集。我不认为 ruby​​ 应该能够知道是否曾经访问过哈希键值。所以我无法解释为什么临时文件在 40% 的情况下消失了。有什么想法吗?
    • 我认为这与您在循环中关闭文件 (cit_file.close) 的事实有关...此外,一些接受块的 File(和 TempFile)方法将在块的末尾自动关闭文件。
    【解决方案3】:

    临时文件在被垃圾回收时被删除(它不再被引用并且内存清理正在释放对象)。

    Ruby documentation中所述:

    当 Tempfile 对象被垃圾回收时,或者当 Ruby 解释器退出时,其关联的临时文件会被自动删除...

    只要您仍然持有对临时对象的引用,就不必担心它会被过早删除。

    【讨论】: