2009-08-31 17 views
3

我有一個web服務方法,讀取一張照片並返回其字節數據。我目前做如下:ruby​​ IO.read()鎖嗎?

@photo_bytes = IO.read("/path/to/file") 
send_data(@photo_bytes, :filename => "filename", :type => "filetype", :disposition => "inline") 

調用這個了很多,當我收到一些奇怪的行爲......偶爾SEND_DATA被返回null。我在想如果一個文件還沒有關閉,也許我正在讀競爭。使用IO.read打開文件後,是否需要顯式關閉文件?我如何使用read_nonblock來做到這一點,它會值得嗎?

UPDATE:

所以我做了一些更多的記錄和偶爾IO.read就像是1800個字節返回一個值時,它通常返回〜用於圖片5800個字節。當它返回1800字節時,圖片不會顯示在客戶端上。當兩個用戶調用Web服務時,這種情況發生得相當隨機。

感謝

湯姆

回答

4

IO.read方法沒有做任何諮詢文件鎖定,所以不應該由其他併發讀者的影響。但是,如果您的應用程序的其他地方有寫入相同路徑的代碼,則需要確保以原子方式更新文件。以write(而不是append)模式打開文件會立即將文件截斷爲零字節,因此,在寫入新版本之前,您可以很清楚地看到上述代碼片段生成的空響應。

假設你是在* NIX平臺,如Linux或OS X,不過,你可以使用原子像這樣的代碼更新文件:

require 'tempfile' 
require 'fileutils' 

def safe_write(path, data) 
    tmp = Tempfile.new 
    tmp.write(data) 
    tmp.close 
    FileUtils.mv(tmp.path, path) 
end 

這將數據寫入到一個臨時文件,然後將它以原子方式到"/path/to/file"的位置,沒有讀者看到零長度的截斷版本。

+0

一旦給定的文件被寫入,它將永遠不會被更新。這是個人資料照片系統。用戶上傳照片,它由多個用戶多次檢索。如果用戶上傳新照片,則會創建一個新文件。當我有很多用戶點擊該網站時,似乎send_data偶爾會發送空值。 – cakeforcerberus 2009-09-01 00:16:10

+0

而「很多」我的意思是兩個。 :) – cakeforcerberus 2009-09-01 00:16:46

+0

哦,另外,我還用<%image_tag filename%>提取數據 - 是否鎖定文件? – cakeforcerberus 2009-09-01 00:18:50