2016-02-24 34 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作为文件名。

相关问题