首页 > 解决方案 > Zlib gunzip 仅返回部分文件

问题描述

我有一个 27MB 的 .gz 文件(解压缩后为 127MB)。使用 ruby​​ 的 Zlib 解压缩文件会返回格式正确的数据,但文件会被截断为预期大小的一小部分(253,000 行数据中的 1290 行数据)。

string_io = StringIO.new(body)
file = File.new("test.json.gz", "w+")
file.puts string_io.read
file.close

# string_io.read.length == 26_675_650
# File.size("test.json.gz") == 27_738_775

使用 GzipReader:

data = ""
File.open(file.path) do |f|
  gz = Zlib::GzipReader.new(f)
  data << gz.read
  gz.close
end
# data.length = 603_537

使用不同的 GzipReader 方法:

data = ""
Zlib::GzipReader.open(file.path) do |gz|
  data << gz.read
end
# data.length == 603_537

使用gunzip:

gz = Zlib.gunzip(string_io.read)
# gz.length == 603_537

预期大小为 127,604,690,但我只能提取 603,537。在我的终端中使用 gunzip 可以正确提取整个文件,但我正在寻找一种编程方式来处理这个问题。

标签: ruby-on-railsrubygzipzlib

解决方案


您是否尝试过使用而不是打开文件并传递文件处理程序Zlib::GzipReader.open()?它记录在这里https://ruby-doc.org/stdlib/libdoc/zlib/rdoc/Zlib/GzipReader.html

我在本地测试并能够得到正确的结果:

data = ''
=> ""

Zlib::GzipReader.open('file.tar.gz') { |gz|
  data << gz.read
}

data.length
=> 750003

然后检查未压缩的文件大小:

gzip -l file.tar.gz                                                                                                                           
  compressed uncompressed  ratio uncompressed_name
      315581       754176  58.1% file.tar

编辑:看到您正在通过 S3 API 提取数据的更新。在将其写入文件之前,请确保您正在对您的正文进行 Base64 解码。


推荐阅读