2013-06-03 32 views
0

我正在创建一个包含文本文件和图像文件的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 
+0

[为什么二进制文件在压缩时损坏?](http://stackoverflow.com/questions/10564283/why-are-binary-files-corrupted-when-zipping-them) –

回答

0

我在阅读Lib文件时遇到类似问题。这里是我的解决方案:

File.open(path + '\Wall.Lib') 

其中路径对应于输入文件名的JavaScript文件。

1

你需要告诉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,那么将自动发生。否则,readreadbin都将读取到EOF并关闭文件。如果输入文件是未知大小或大于可用缓冲区空间,则使用这些方法的代码需要对读取块的需求敏感。

+0

这个文件被打开将永远不会关闭。使用'File.binread(file_name)'。 –

相关问题