ruby - lenguajes - lambda management
Creación de un nombre de archivo temporal seguro para subprocesos (3)
Como solo necesita el nombre de archivo, ¿qué hay de usar SecureRandom para eso?
require ''securerandom''
filename = "#{SecureRandom.hex(6)}.png" #=> "0f04dd94addf.png"
También puedes usar SecureRandom.alphanumeric
Cuando se usa Tempfile
Ruby está creando un archivo con un nombre seguro para subprocesos y seguro entre procesos. Sólo necesito un nombre de archivo de esa manera.
Me preguntaba si hay un enfoque más directo que:
t = Tempfile.new([''fleischwurst'', ''.png''])
temp_path = t.path
t.close
t.unlink
Encontré que la solución Dir: Tmpname no funcionó para mí. Al evaluar esto:
Dir::Tmpname.make_tmpname "/tmp/blob", nil
Bajo MRI Ruby 1.9.3p194 me sale:
uninitialized constant Dir::Tmpname (NameError)
Bajo JRuby 1.7.5 (1.9.3p393) obtengo:
NameError: uninitialized constant Dir::Tmpname
Podrías probar algo como esto:
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
Excavando en tempfile.rb
notará que Tempfile
incluye Dir::Tmpname
. Dentro encontrarás make_tmpname
que hace lo que pides.
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"
En el mismo archivo, también está Dir::Tmpname.create
que, dependiendo de lo que quieras lograr, hace un poco más que make_tmpname
. En particular, determina qué directorio temporal usar (asumiendo que no está en * nix donde /tmp
es una suposición globalmente correcta). Aún así, un poco feo de usar ya que espera un bloque:
Dir::Tmpname.create([''a'', ''.png'']) { }
# => "/tmp/a20140224-15930-l9sc6n.png"
El bloque está ahí para que el código pruebe si el archivo existe y Errno::EEXIST
un Errno::EEXIST
para que se pueda generar un nuevo nombre con un valor incremental etiquetado al final.