Ruby 为什么此文件上载代码会损坏我的MP3文件?

Ruby 为什么此文件上载代码会损坏我的MP3文件?,ruby,file-upload,upload,sinatra,Ruby,File Upload,Upload,Sinatra,我有一个基于Sinatra的项目,用户可以上传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="fil

我有一个基于Sinatra的项目,用户可以上传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>
上载文件时,文件已损坏:

  • Windows Media Player中MP3文件的图像失真
  • 声音已损坏(听起来不正确)

  • 如何修复它?

    您正在以文本模式(默认模式)打开文件:

    但你写的是二进制数据(MP3)。您需要在以下位置打开目标文件:


    此外,在没有彻底清除的情况下,不应使用用户提供的名称(
    params['song'][:filename]
    )作为文件名;或者更好的做法是,完全不要使用他们的名字,将他们的名字存储在数据库中的某个位置,并使用表的
    id
    作为文件名。

    您是否正在这样做
    文件。在Windows框中打开
    ?@muistooshort是的,Windows 7。
    
    post "/upload" do 
      File.open('uploads/' + params['song'][:filename], "w") do |f|
        f.write(params['song'][:tempfile].read)
      end
      erb :main
    end
    
    File.open('uploads/' + params['song'][:filename], "w")
    
    "b"  Binary file mode
         Suppresses EOL <-> CRLF conversion on Windows. And
         sets external encoding to ASCII-8BIT unless explicitly
         specified.
    
    File.open('uploads/' + params['song'][:filename], "wb")
    # --------------------------------------------------^