如何将临时文件编写为二进制文件

Gij*_*des 4 ruby ruby-on-rails ruby-on-rails-5

当尝试通过执行以下操作将字符串/解压缩文件写入Tempfile 时

temp_file = Tempfile.new([name, extension])
temp_file.write(unzipped_io.read)
Run Code Online (Sandbox Code Playgroud)

当我对图像执行此操作时会引发以下错误:

Encoding::UndefinedConversionError - "\xFF" from ASCII-8BIT to UTF-8
Run Code Online (Sandbox Code Playgroud)

在研究它时,我发现这是因为 Ruby 尝试使用默认编码 (UTF-8) 编写文件。但是该文件应该写为二进制文件,因此它会忽略任何特定于文件的行为。

编写常规,File您可以按以下方式执行此操作:

File.open('/tmp/test.jpg', 'rb') do |file| 
  file.write(unzipped_io.read)
end
Run Code Online (Sandbox Code Playgroud)

如何做到这一点 Tempfile

Ste*_*fan 7

Tempfile.new将选项传递给File.open接受来自IO.new选项,特别是:

:binmode
如果值为真值,则与argument中的“b”相同mode

因此,要以二进制模式打开临时文件,您可以使用:

temp_file = Tempfile.new([name, extension], binmode: true)

temp_file.binmode?          #=> true
temp_file.external_encoding #=> #<Encoding:ASCII-8BIT>
Run Code Online (Sandbox Code Playgroud)

此外,您可能希望使用Tempfile.createwhich 接受一个块并在之后自动关闭并删除文件:

Tempfile.create([name, extension], binmode: true) do |temp_file|
  temp_file.write(unzipped_io.read)
  # ...
end
Run Code Online (Sandbox Code Playgroud)