Ruby: 有没有办法在 File.write 中指定编码?

Ruby: Is there a way to specify your encoding in File.write?

TL;DR

如何在 File.write 上指定编码模式,或者如何以类似的方式将图像二进制文件保存到文件?

更多详情

我正在尝试从 Trello 卡下载图像,然后将该图像上传到 S3,以便它具有可访问性 URL。我已经能够从 Trello 下载图像为二进制文件(我相信它是某种形式的二进制文件),但我一直在使用 File.write 将其保存为 .jpeg 时遇到问题。每次我尝试这样做时,它都会在我的 Rails 控制台中给我这个错误:

Encoding::UndefinedConversionError: "\xFF" from ASCII-8BIT to UTF-8
from /app/app/services/customer_order_status_notifier/card.rb:181:in `write'

这里是触发的代码:

def trello_pics
    @trello_pics ||=
    card.attachments.last(config_pics_number)&.map(&:url).map do |url|
      binary = Faraday.get(url, nil, {'Authorization' => "OAuth oauth_consumer_key=\"#{ENV['TRELLO_PUBLIC_KEY']}\", oauth_token=\"#{ENV['TRELLO_TOKEN']}\""}).body
      File.write(FILE_LOCATION, binary) # doesn't work
      run_me
    end
  end

所以我认为这一定是 File.write 将输入转换为文件的方式的问题。有没有办法指定编码?

AFIK 你不能在执行 write 时这样做,但你可以在创建 File 对象时这样做;这里有一个 UTF8 编码的例子:

File.open(FILE_LOCATION, "w:UTF-8") do 
  |f|
  f.write(....)
end

另一种可能性是使用 external_encoding 选项:

File.open(FILE_LOCATION, "w", external_encoding: Encoding::UTF_8)

当然这假设写入的数据是String。如果您有(打包的)二进制数据,您将使用 "wb" 打开文件,并使用 syswrite 而不是 write 将数据写入文件。

UPDATE 正如 engineersmnky 在评论中指出的那样,编码的参数也可以作为参数传递给 write 方法本身,例如

IO::write(FILE_LOCATION, data_to_write, external_encoding: Encoding::UTF_8)