使用Tempfile
时,Ruby正在创建一个具有线程安全和进程间安全名称的文件。我只需要这样的文件名。
我想知道是否有更直接的方法:
t = Tempfile.new(['fleischwurst', '.png'])
temp_path = t.path
t.close
t.unlink
答案 0 :(得分:55)
挖掘tempfile.rb
您会注意到Tempfile
包含Dir::Tmpname
。在里面,你会找到make_tmpname
来完成你所要求的。
Dir::Tmpname.make_tmpname "/tmp/źdźbło", nil
# => "/tmp/źdźbło20121209-1867-1qyptqe"
Dir::Tmpname.make_tmpname(['a', '.png'], nil)
# => "a20121209-2710-wcjbzr.png"
在同一个文件中,还有Dir::Tmpname.create
,根据您要实现的目标,它会比make_tmpname
稍微多一点。特别是,它确定了要使用的临时目录(假设你不在{nix,其中/tmp
是一个全局正确的假设)。尽管如此,它还是有点丑陋,因为它需要一个块:
Dir::Tmpname.create(['a', '.png']) { }
# => "/tmp/a20140224-15930-l9sc6n.png"
该块用于测试文件是否存在的代码并引发Errno::EEXIST
,以便生成一个新名称,并在末尾标记增量值。
答案 1 :(得分:0)
由于只需要文件名,因此使用SecureRandom会怎样:
require 'securerandom'
filename = "#{SecureRandom.hex(6)}.png" #=> "0f04dd94addf.png"
您也可以使用SecureRandom.alphanumeric
答案 2 :(得分:0)
由于Dir::Tmpname.make_tmpname
是removed in Ruby 2.5.0,因此此后退到使用SecureRandom
:
require "tmpdir"
def generate_temp_filename(ext=".png")
filename = begin
Dir::Tmpname.make_tmpname(["x", ext], nil)
rescue NoMethodError
require "securerandom"
"#{SecureRandom.urlsafe_base64}#{ext}"
end
File.join(Dir.tmpdir, filename)
end
答案 3 :(得分:-2)
我发现Dir:Tmpname解决方案对我不起作用。评估时:
Dir::Tmpname.make_tmpname "/tmp/blob", nil
在MRI Ruby 1.9.3p194下,我得到:
uninitialized constant Dir::Tmpname (NameError)
在JRuby 1.7.5(1.9.3p393)下,我得到:
NameError: uninitialized constant Dir::Tmpname
您可以尝试这样的事情:
def temp_name(file_name='', ext='', dir=nil)
id = Thread.current.hash * Time.now.to_i % 2**32
name = "%s%d.%s" % [file_name, id, ext]
dir ? File.join(dir, name) : name
end