When using Tempfile
Ruby is creating a file with a thread-safe and inter-process-safe name. I only need a file name in that way.
I was wondering if there is a more straight forward approach way than:
t = Tempfile.new(['fleischwurst', '.png'])
temp_path = t.path
t.close
t.unlink
Digging in tempfile.rb
you'll notice that Tempfile
includes Dir::Tmpname
. Inside you'll find make_tmpname
which does what you ask for.
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"
In the same file, there's also Dir::Tmpname.create
which, depending on what you want to achieve, does a little more than make_tmpname
. In particular, it figures out what temporary directory to use (assuming you're not on *nix where /tmp
is a globally correct assumption). Still, a little ugly to use given that it expects a block:
Dir::Tmpname.create(['a', '.png']) { }
# => "/tmp/a20140224-15930-l9sc6n.png"
The block is there for code to test if the file exists and raise an Errno::EEXIST
so that a new name can be generated with incrementing value tagged on the end.
Since you only need the filename, what about using the SecureRandom for that:
require 'securerandom'
filename = "#{SecureRandom.hex(6)}.png" #=> "0f04dd94addf.png"
You can also use SecureRandom.alphanumeric
I found the Dir:Tmpname solution did not work for me. When evaluating this:
Dir::Tmpname.make_tmpname "/tmp/blob", nil
Under MRI Ruby 1.9.3p194 I get:
uninitialized constant Dir::Tmpname (NameError)
Under JRuby 1.7.5 (1.9.3p393) I get:
NameError: uninitialized constant Dir::Tmpname
You might try something like this:
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