当使用Tempfile时,Ruby将使用线程安全和进程间安全的名称创建文件。我只需要一个文件名。

我想知道是否有比以下更直接的方法:

t = Tempfile.new(['fleischwurst', '.png'])
temp_path = t.path
t.close
t.unlink

最佳答案

Dir::Tmpname.create

您可以使用Dir::Tmpname.create。它指出要使用的临时目录(除非您将目录传递给它)。考虑到它会阻塞,所以使用起来有点难看:

require 'tmpdir'
# => true
Dir::Tmpname.create(['prefix-', '.ext']) {}
# => "/tmp/prefix-20190827-1-87n9iu.ext"
Dir::Tmpname.create(['prefix-', '.ext'], '/my/custom/directory') {}
# => "/my/custom/directory/prefix-20190827-1-11x2u0h.ext"

该代码块用于测试文件是否存在并引发Errno::EEXIST,以便可以生成新名称,并在末尾附加递增值。

Rails解决方案

Ruby on Rails实现的解决方案简短,类似于最初在Ruby中实现的解决方案:
require 'tmpdir'
# => true
File.join(Dir.tmpdir, "YOUR_PREFIX-#{Time.now.strftime("%Y%m%d")}-#{$$}-#{rand(0x100000000).to_s(36)}-YOUR_SUFFIX")
=> "/tmp/YOUR_PREFIX-20190827-1-wyouwg-YOUR_SUFFIX"
File.join(Dir.tmpdir, "YOUR_PREFIX-#{Time.now.strftime("%Y%m%d")}-#{$$}-#{rand(0x100000000).to_s(36)}-YOUR_SUFFIX")
=> "/tmp/YOUR_PREFIX-20190827-1-140far-YOUR_SUFFIX"

Dir::Tmpname.make_tmpname(Ruby 2.5.0和更早版本)



挖掘tempfile.rb,您会发现Tempfile包括Dir::Tmpname。在内部,您会找到 make_tmpname ,它可以满足您的要求。
require 'tmpdir'
# => true
File.join(Dir.tmpdir, Dir::Tmpname.make_tmpname("prefix-", nil))
# => "/tmp/prefix-20190827-1-dfhvld"
File.join(Dir.tmpdir, Dir::Tmpname.make_tmpname(["prefix-", ".ext"], nil))
# => "/tmp/prefix-20190827-1-19zjck1.ext"
File.join(Dir.tmpdir, Dir::Tmpname.make_tmpname(["prefix-", ".ext"], "suffix"))
# => "/tmp/prefix-20190827-1-f5ipo7-suffix.ext"

09-06 06:47