2012-12-09 35 views
28

Khi sử dụng Tempfile Ruby đang tạo tệp có tên an toàn và an toàn liên tiến trình. Tôi chỉ cần một tên tập tin theo cách đó.Tạo tên tệp tạm thời chỉ an toàn chủ đề

tôi đã tự hỏi nếu có một cách tiếp cận thẳng về phía trước cách hơn:

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

Trả lời

51

Đào trong tempfile.rb bạn sẽ nhận thấy rằng Tempfile bao gồm Dir::Tmpname. Bên trong, bạn sẽ tìm thấy make_tmpname làm những gì bạn yêu cầu.

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" 

Trong cùng một tập tin, cũng có Dir::Tmpname.create đó, tùy thuộc vào những gì bạn muốn đạt được, không một chút hơn make_tmpname. Đặc biệt, nó tìm ra những thư mục tạm thời để sử dụng (giả sử bạn không ở trên * nix nơi /tmp là một giả định chính xác toàn cầu). Tuy nhiên, một chút xấu xí để sử dụng cho rằng nó hy vọng một khối:

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

Khối là có cho mã để kiểm tra nếu tập tin tồn tại và nâng cao một Errno::EEXIST để một cái tên mới có thể được tạo ra với incrementing giá trị gắn thẻ trên kết thúc.

+0

Cảm ơn, đúng vậy. Có thể được sử dụng với đối số mảng để bảo toàn phần mở rộng tên tệp: 'Dir :: Tmpname.make_tmpname (['a', '.png'], nil)' – iltempo

+0

@iltempo, bạn được chào đón. Tôi đã thêm ví dụ của bạn vào câu trả lời. – Jan

+1

Điều này là tuyệt vời nhưng không ai đã đề cập rằng bạn cần 'yêu cầu 'tmpdir'' để làm việc này. – KingBob

-2

Tôi thấy giải pháp Dir: Tmpname không hoạt động đối với tôi. Khi đánh giá này:

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

Dưới MRI của Ruby 1.9.3p194 tôi nhận được:

uninitialized constant Dir::Tmpname (NameError) 

Dưới JRuby 1.7.5 (1.9.3p393) tôi nhận được:

NameError: uninitialized constant Dir::Tmpname 

Bạn có thể thử một cái gì đó như thế này:

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

Trước khi bạn sử dụng Dir :: Tempname id bạn yêu cầu 'tempfile' yêu cầu 'tempfile' Dir :: Tmpname.make_tmpname "/ tmp/blob", nil Nếu bạn chưa tải 'Tempfile' thì bạn sẽ không có thể sử dụng các tiện ích mở rộng của nó cho Dir –

+0

@ScottThompson Có, cảm ơn. – dinman2022