【问题标题】:Failure reading PNG files with Ruby on Windows在 Windows 上使用 Ruby 读取 PNG 文件失败
【发布时间】:2013-06-03 19:37:32
【问题描述】:

我正在创建一个包含文本文件和图像文件的 Zip 文件。该代码在 MacOS 上运行时按预期工作,但在 Windows 上运行时由于图像文件内容未正确读取而失败。

下面的 sn-p 总是将 PNG 图像文件读取为 '‰PNG',在 Zip 中为每个 PNG 图像添加一个 5 字节的文件。

是 Windows 环境的问题吗?

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

【问题讨论】:

标签: ruby windows zip png


【解决方案1】:

来自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】:

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

    【讨论】:

    • 被打开的文件永远不会被关闭。使用File.binread(file_name)
    【解决方案3】:

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

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

    路径对应于输入文件名的 javascript 文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-27
      • 2021-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      相关资源
      最近更新 更多