为什么从ASCII-8BIT到UTF-8会出现字符串编码问题“\ xE2”?

我正在尝试从电子邮件下载PDF并将内容写入文件。 出于某种原因,我收到此错误:

An Encoding::UndefinedConversionError occurred in attachments#inbound: "\xE2" from ASCII-8BIT to UTF-8 app/controllers/api/attachments_controller.rb:70:in `write' 

这是我的代码:

 def inbound if Rails.env.production? or Rails.env.staging? email = Postmark::Mitt.new(request.body.read) else email = Postmark::Mitt.new(File.binread "#{Rails.root}/app/temp_pdfs/email.json") end if email.attachments.count == 0 # notify aidin that we got an inbound email with no attachments respond_to do |format| format.json { head :no_content } end return end attachment = email.attachments.first filename = "attachment" + (Time.now.strftime("%Y%m%d%H%M%S")+(rand * 1000000).round.to_s) + ".pdf" base_path = "#{Rails.root}/temp_attachments/" unless File.directory?(base_path) Dir::mkdir(base_path) end file = File.new base_path + filename, 'w+' file.write Base64.decode64(attachment.source['Content'].encode("UTF-16BE", :invalid=>:replace, :replace=>"?").encode("UTF-8")) file.close write_options = write_options() write_options[:metadata] = {:filename => attachment.file_name, :content_type => attachment.content_type, :size => attachment.size } obj = s3_object() file = File.open file.path obj.write(file.read, write_options) file.close FaxAttach.trigger obj.key.split('/').last render :nothing => true, :status => 202 and return end 

我看了看,看起来解决这个问题的方法是:

 file.write Base64.decode64(attachment.source['Content'].encode("UTF-16BE", :invalid=>:replace, :replace=>"?").encode("UTF-8")) 

但它似乎没有用。

错误消息实际上是在文件写入时抛出的,而不是在params内部的编码/解码,因为Ruby正在尝试在file.write上应用默认字符编码。 为了防止这种情况,最快的解决方法是在打开文件时添加b标志

 file = File.new base_path + filename, 'wb+' file.write Base64.decode64( attachment.source['Content'] ) 

这是假设传入的附件在Base64中编码,正如您的代码所暗示的那样(我无法validation这一点)。 存储在attachment.source['Content']的Base64编码应该是ASCII-8BIT和UTF-8中的相同字节,因此在调用decode64内没有任何意义。