2016-02-24 35 views
1

我有一個基於Sinatra的項目,其中page,用戶可以上傳MP3文件。爲什麼這個文件上傳代碼會損壞我的MP3文件?

<h2><%= I18n.t(:home_title) %></h2> 
<%= I18n.t(:upload_body_text) %> 
<form action="/<%= I18n.locale %>/upload" method="post" enctype="multipart/form-data"> 
<p> 
<input type="file" name="song" size="40"> 
</p> 
<div> 
<input type="submit" value="<%= I18n.t(:home_submit) %>"> 
</div> 
</form> 

上載該route處理:

post "/upload" do 
    File.open('uploads/' + params['song'][:filename], "w") do |f| 
    f.write(params['song'][:tempfile].read) 
    end 
    erb :main 
end 

當文件被上傳,它的損壞:

  1. 在Windows Media Player中的MP3文件的圖像失真。
  2. 聲音被破壞(聽起來不對)。

我該如何解決?

+0

你是否在Windows盒子上執行'File.open'? –

+0

@ muistooshort是的,Windows 7。 –

回答

3

你打開在文本模式(默認)文件:

File.open('uploads/' + params['song'][:filename], "w") 

,但你寫的二進制數據(MP3)。您需要binary mode打開目標文件:

"b" Binary file mode 
    Suppresses EOL <-> CRLF conversion on Windows. And 
    sets external encoding to ASCII-8BIT unless explicitly 
    specified. 

或IO庫將嘗試EOLS轉換爲Windows風格的CR-LF對:

File.open('uploads/' + params['song'][:filename], "wb") 
# --------------------------------------------------^ 

而且,你不應該使用用戶提供的名稱(params['song'][:filename])作爲文件名而不徹底清理它;或更好的,不要使用他們的名字,將他們的名字存儲在某個數據庫中,並使用表格的id作爲文件名。

相關問題