我正在创建一个包含文本文件和图像文件的Zip文件。代码在MacOS上运行时按预期工作,但在Windows上运行时会失败,因为图像文件内容读取不正确。在Windows上使用Ruby读取PNG文件失败
下面的代码段总是将PNG图像文件读取为'PNG',在Zip中为每个PNG图像添加一个5字节的文件。
这是Windows环境的问题吗?
zip_fs.file.open(destination, 'w') do |f|
f.write File.read(file_name)
end
我正在创建一个包含文本文件和图像文件的Zip文件。代码在MacOS上运行时按预期工作,但在Windows上运行时会失败,因为图像文件内容读取不正确。在Windows上使用Ruby读取PNG文件失败
下面的代码段总是将PNG图像文件读取为'PNG',在Zip中为每个PNG图像添加一个5字节的文件。
这是Windows环境的问题吗?
zip_fs.file.open(destination, 'w') do |f|
f.write File.read(file_name)
end
我在阅读Lib文件时遇到类似问题。这里是我的解决方案:
File.open(path + '\Wall.Lib')
其中路径对应于输入文件名的JavaScript文件。
从Why are binary files corrupted when zipping them?
io.get_output_stream(zip_file_path) do |out|
out.write File.binread(disk_file_path)
end
你需要告诉Ruby来读/以二进制方式写入文件。这里有一个主题一些变化:
zip_fs.file.open(destination, 'wb') do |f|
File.open(file_name, 'rb') do |fi|
f.write fi.read
end
end
zip_fs.file.open(destination, 'wb') do |f|
f.write File.read(file_name, 'mode' => 'rb')
end
zip_fs.file.open(destination, 'wb') do |f|
f.write File.readbin(file_name)
end
与代码的一个潜在问题是输入文件被咕噜咕噜,而如果它比可用空间大,将是一件坏事。最好是以块的形式读取输入文件。这是未经测试,但应该工作:
BLOCK_SIZE = 1024 * 1024
zip_fs.file.open(destination, 'wb') do |f|
File.open(file_name, 'rb') do |fi|
while (block_in = fi.read(BLOCK_SIZE)) do
f.write block_in
end
end
end
已打开永远不会关闭该文件。使用File.binread
我最初的代码被写入显示时需要使用二进制模式,并用open
,因为它是“传统的”,却忘了使用块模式(FILE_NAME)。我修改了示例代码来解决这个问题。
但是,当脚本结束时解释器关闭时,该文件将由Ruby隐式关闭,作为发生的内务处理的一部分。但是,最好明确close
该文件。如果OP使用我认为的RubyZip,那么如果一个块被传递给open
,那么将自动发生。否则,read
和readbin
都将读取到EOF并关闭文件。如果输入文件是未知大小或大于可用缓冲区空间,则使用这些方法的代码需要对读取块的需求敏感。
这个文件被打开将永远不会关闭。使用'File.binread(file_name)'。 –
[为什么二进制文件在压缩时损坏?](http://stackoverflow.com/questions/10564283/why-are-binary-files-corrupted-when-zipping-them) –