如果我通过Tempfile
创建了一个临时文件,除了将其复制到我可以"永久"的另一个文件之外,还有什么办法?当关联的Tempfile
实例被收集或终止过程时,我想避免将其删除。
在相关点上,是否有一种方法可以利用Tempfile
机制(或使用类似的机制)获取"新"文件名,而无需以该名称创建文件?
不是真的。对于问题本身,请参阅:
ObjectSpace.undefine_finalizer(tmpfile)
Tempfile库使用Ruby Objectspace结尾器在垃圾收集中自动删除自身。通过使用上线,您可以删除temfile的能力,如果您不删除它。因此,例如:
$ irb
2.0.0p0 :001 > require "tempfile"
=> true
2.0.0p0 :002 > t = Tempfile.new("test")
=> #<Tempfile:/tmp/test20140122-6655-80p4b7>
2.0.0p0 :003 > t.write("Hi!")
=> 3
2.0.0p0 :004 > ObjectSpace.undefine_finalizer(t)
=> #<Tempfile:/tmp/test20140122-6655-80p4b7>
2.0.0p0 :005 > exit
$ cat /tmp/test20140122-6655-80p4b7
Hi!
$
不过还有其他需要注意的东西。Tempfile将使用系统临时文件目录(例如/tmp
)自动偶尔清洁(例如,在每个引导中)。因此,即使您"坚持"了该文件,您也需要对其消失,或者将其移至默认情况下不会清理的目录,例如/var/tmp
(持续临时文件的Linux目录)。
至于您的第二个问题,请尝试此处:
Dir::Tmpname.create('your_application_prefix') { |path| puts path }
它需要一个require "tmpdir"
。
我认为最简单的解决方案可能是猴子修补Tmpfile
类以添加persist
方法。此方法以将临时文件移至的文件名为单位。此外,它删除了最终制度,因此不会在退出处删除临时文件。
require 'tempfile'
require 'fileutils'
class Tempfile
def persist(filename)
FileUtils.mv(self.path, filename)
ObjectSpace.undefine_finalizer(self)
end
end
file = Tempfile.new('tmp')
file.write('hello world')
file.close
file.persist('hello.txt')
运行此程序将通过移动原始临时文件而不是复制它来创建一个持久的文件./hello.txt
。