我正在创建一个包含文本文件和图像文件的 Zip 文件。该代码在 MacOS 上运行时按预期工作,但在 Windows 上运行时失败,因为未正确读取图像文件内容。
下面的代码片段总是将 PNG 图像文件读取为“‰PNG”,在 Zip 中为每个 PNG 图像添加一个 5 字节的文件。
这是关于Windows环境的问题吗?
zip_fs.file.open(destination, 'w') do |f|
f.write File.read(file_name)
end
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
代码的一个潜在问题是输入文件被 slurped,如果它大于可用空间,那将是一件坏事。最好以块的形式读取输入文件。这是未经测试的,但应该可以工作:
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(file_name)
我编写的初始代码是为了表明需要使用二进制模式,并且使用open
它是因为它“更传统”,但忘记使用块模式。我修改了我的示例代码来解决这个问题。
但是,当脚本结束时解释器关闭时,Ruby 会隐式关闭文件,这是发生的内务处理的一部分。但是,最好明确close
文件。如果 OP 像我想的那样使用RubyZip,那么如果将一个块传递给open
. 否则,read
将readbin
同时读取 EOF 并关闭文件。如果输入文件的大小未知或大于可用缓冲区空间,则使用这些方法的代码需要对读取块的需求敏感。
我在阅读 Lib 文件时遇到了类似的问题。这是我的解决方案:
File.open(path + '\Wall.Lib')
路径对应于输入文件名的 javascript 文件。