Failure reading PNG files with Ruby on Windows

对着背影说爱祢 提交于 2020-01-03 05:16:33

问题


I am creating a Zip file containing both text files and image files. The code works as expected when running on MacOS, but it fails when running on Windows because the image file contents are not read correctly.

The snippet below always reads PNG image files as '‰PNG', adding a 5 bytes file in the Zip for each PNG image.

Is it an issue regarding Windows environment?

zip_fs.file.open(destination, 'w') do |f|
  f.write File.read(file_name)
end

回答1:


from 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



回答2:


You need to tell Ruby to read/write the files in binary mode. Here are some variations on a theme:

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

A potential problem with the code is the input file is being slurped, which, if it's larger than the available space, would be a bad thing. It'd be better to read the input file in blocks. This is untested but should work:

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

The file that was opened will never be closed. Use File.binread(file_name)

My initial code was written to show that binary mode needed to be used, and used open because it's "more traditional", but forgot to use the block mode. I modified my sample code to fix that problem.

However, the file would be closed implicitly by Ruby as the interpreter shuts down when the script ends, as part of housekeeping that occurs. However, it's better to explicitly close the file. If the OP is using RubyZip like I think, that will automatically happen if a block is passed to open. Otherwise, read and readbin will both read to EOF and close the file. Code using those methods needs to be sensitive to the need to read blocks if the input file is an unknown size or larger than available buffer space.




回答3:


I had a similar problem when I was reading Lib files. Here's my solution:

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

Where the path corresponded to a javascript file that inputs filenames.



来源:https://stackoverflow.com/questions/16904518/failure-reading-png-files-with-ruby-on-windows

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!