Welcome 微信登录

首页 / 软件开发 / JAVA / Rails文件上传file_field报错Encoding::UndefinedConversionError

Rails文件上传file_field报错Encoding::UndefinedConversionError2013-12-11 突破中的IT结构师 服务器用的是ubuntu12 64bit,环境是ruby1.9.3+rails3+mysql,测试是在windows2003上。

上传 一个【.gitconfig】文件,没有问题,上传【新浪微博数据挖掘.pdf】报错,上传【back.jpg】报错。

下 面是两段信息,是从【log/production.log】中粘贴出来的。上面一段你是没有问题的日志,下面一段是报错 之后的日志。

01.Started POST "/posts" for 106.3.102.43 at 2012-10-29 21:16:26 +0800
02.Processing by PostsController#create as HTML
03. Parameters: {"utf8"=>"?", "authenticity_token"=>"QG8aU6/VW5ZMagzyGhjdbm7fSzr4MB5CKdJeGBIeOa4=", "post"=>{"category_id"=>"1", "title"=>"666666666666", "url"=>"6666666", "picture"=>#<ActionDispatch::Http::UploadedFile:0x000000032fb838 @original_filename=".gitconfig", @content_type="application/octet-stream", @headers="Content-Disposition: form-data; name="post[picture]"; filename=".gitconfig" Content-Type: application/octet-stream ", @tempfile=#<File:/tmp/RackMultipart20121029-2609-1lrmc9o>>, "content"=>"6666", "tags_attributes"=>{"0"=> {"title"=>""}}}, "commit"=>"Create Post"}
04.Redirected to http://42.121.5.68/posts
05.Completed 302 Found in 36ms (ActiveRecord: 30.1ms)
01.Started POST "/posts" for 123.114.36.100 at 2012-10-30 08:58:13 +0800
02.Processing by PostsController#create as HTML
03. Parameters: {"utf8"=>"?", "authenticity_token"=>"rRnhcDWYDn+OntxxC2LmIEHpSpjWI5glrs6JlprG1Ho=", "post"=>{"category_id"=>"1", "title"=>"博 客尝试最新法宝", "url"=>"post7", "picture"=>#<ActionDispatch::Http::UploadedFile:0x000000030df9a0 @original_filename="新浪微博数据挖掘方案.pdf", @content_type="binary/octet- stream", @headers="Content-Disposition: form-data; name="post[picture]"; filename="xE6x96xB0xE6xB5xAAxE5xBExAExE5x8Dx9AxE6x95xB0xE6x8DxAExE6 x8Cx96xE6x8Ex98xE6x96xB9xE6xA1x88.pdf" Content-Type: binary/octet- stream ", @tempfile=#<File:/tmp/RackMultipart20121030-16129-15agvlb>>, "content"=>"博客尝>试最新法宝", "tags_attributes"=> {"0"=>{"title"=>"博客尝试最新法宝"}}}, "commit"=>"Create Post"}
04.Completed 500 Internal Server Error in 45ms
05.
06.Encoding::UndefinedConversionError ("xE2" from ASCII-8BIT to UTF-8):
07. app/controllers/posts_controller.rb:60:in `write"
08. app/controllers/posts_controller.rb:60:in `block (2 levels) in create"
09. app/controllers/posts_controller.rb:59:in `open"
10. app/controllers/posts_controller.rb:59:in `block in create"
11. app/controllers/posts_controller.rb:56:in `create"

比较之后,发现两段的picture部分的@content_type不一样,成功的是 @content_type="application/octet-stream",失败的是@content_type="binary/octet- stream"。

尝试上传一个txt文件,成功了,@content_type部分是 @content_type="text/plain"。

确定是这个部分的原因,也就是编码,所以报错编码错误,未 定义编码转换。

上传部分的代码如下

uploaded_io = params[:post][:picture] if uploaded_io != nil and uploaded_io.content_type.match("image")File.open(Rails.root.join("public","uploads",uploaded_io.original_filename),"w") do |f|f.write(uploaded_io.read) endelseend
经过一番查找,找到了深层的原因,原来是二进制文件的缘故,ruby在读取和保存的时候会自动 处理二进制文件,不需要特殊的方式。

可是在windows中,二进制和文本文件是不同的,在二进制mode 下,结束行不能被转义为一个单独的换行,而是被保存为一个回车和一个换行。所以如果读取的是二进制文件 ,需要在open的时候要指明读取的是二进制文件wb。b就是二进制的意思。

图片默认按照二进制文件处 理,所以就中招了。其实也只需要把w改成wb就可以了。