2012-12-09 9 views
28

Bei Verwendung von Tempfile erstellt Ruby eine Datei mit einem threadsicheren und interprozesssicheren Namen. Ich brauche nur einen Dateinamen auf diese Weise.Erstellen eines threadsicheren temporären Dateinamens

ich mich gefragt, ob es eine eher geradliniger Ansatz Art und Weise als ist:

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

Antwort

51

in tempfile.rb Graben werden Sie feststellen, dass TempfileDir::Tmpname enthalten. Im Inneren finden Sie make_tmpname, die das tut, was Sie verlangen.

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 der gleichen Datei gibt es auch Dir::Tmpname.create, die, je nachdem, was Sie erreichen wollen, tut ein wenig mehr als make_tmpname. Insbesondere ermittelt es, welches temporäre Verzeichnis zu verwenden ist (vorausgesetzt, Sie sind nicht auf * nix, wobei /tmp eine global korrekte Annahme ist). Trotzdem, ein wenig hässlich gegeben zu verwenden, dass sie einen Block erwartet:

Dir::Tmpname.create(['a', '.png']) { } 
# => "/tmp/a20140224-15930-l9sc6n.png" 

Der Block ist für Code, wenn die Datei so ein Errno::EEXIST und erhöhen besteht zu testen, ob ein neuer Name Wert markiert erzeugt werden kann, auf mit Inkrementieren das Ende.

+0

Danke, das ist es. Kann auch mit einem Array-Argument verwendet werden, um die Dateinamenerweiterung beizubehalten: 'Dir :: Tmpname.make_tmpname (['a', '.png'], nil)' – iltempo

+0

@iltempo, gern geschehen. Ich habe dein Beispiel der Antwort hinzugefügt. – Jan

+1

Das ist großartig, aber niemand hat erwähnt, dass Sie 'tmpdir'requirieren müssen, damit dies funktioniert. – KingBob

-2

Ich fand die Dir: Tmpname Lösung funktionierte nicht für mich. Wenn diese Auswertung:

Dir::Tmpname.make_tmpname "/tmp/blob", nil 

Unter MRI Ruby-1.9.3p194 ich:

uninitialized constant Dir::Tmpname (NameError) 

Unter JRuby 1.7.5 (1.9.3p393) erhalte ich:

NameError: uninitialized constant Dir::Tmpname 

Sie könnten versuchen, etwas wie dieses:

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 
+4

Bevor Sie Dir :: Tempname id verwendet man 'tempfile' require 'tempfile' Dir :: Tmpname.make_tmpname "/ tmp/Blob", nil benötigen Wenn Sie nicht 'Tempfile' geladen haben, dann werden Sie nicht in der Lage sein, seine Erweiterungen zu Dir zu verwenden –

+0

@ScottThompson Ja, danke. – dinman2022

Verwandte Themen