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

chi*_*ikh 15 ruby string ascii ruby-on-rails utf-8

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

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

这是我的代码:

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
Run Code Online (Sandbox Code Playgroud)

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

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

但它似乎没有用.

Nei*_*ter 24

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

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

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