Zlib gunzip возвращает только частичный файл - PullRequest
1 голос
/ 16 октября 2019

У меня есть файл размером 27 МБ .gz (распакованный 127 МБ). Использование ruby's Zlib для распаковки файла возвращает правильно отформатированные данные, но файл усекается до части ожидаемого размера (1290 строк данных из 253 000).

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, но я могу извлечь только 603537. Использование gunzip в моем терминале правильно извлекает весь файл, но я ищу программный способ справиться с этим.

1 Ответ

2 голосов
/ 16 октября 2019

Вместо того, чтобы открывать файл и передавать обработчик файла, вы пытались использовать 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 декодирует ваше тело перед записью в файл.

...