Ruby: Как читать сжатые данные из файла или STDIN?

Я хотел бы прочитать данные из входного файла или STDIN - входные данные могут быть заархивированы.

Для файлов это можно сделать с помощью Zlib::GzipReader следующим образом:

require 'zlib'

ios = File.open(file, mode='r')

begin
  ios = Zlib::GzipReader.new(ios)
rescue
  ios.rewind
end

ios.each_line { |line| puts line }

Однако мне не удается правильно определить заархивированные данные из STDIN:

require 'zlib'

if STDIN.tty?
  # do nothing
else
  ios = STDIN

  begin
    ios = Zlib::GzipReader.new(ios)
  rescue
    ios.rewind
  end
end

ios.each_line { |line| puts line }

Вышеупомянутое работает с gzip-данными в STDIN, но обычные данные приводят к следующему:

./test.rb:14:in `rewind': Illegal seek - <STDIN> (Errno::ESPIPE)
        from ./test.rb:14:in `rescue in <main>'
        from ./test.rb:11:in `<main>'

Итак, если я не могу перемотать STDIN, как мне проверить, заархивированы ли данные в STDIN или нет?

Ваше здоровье,

Мартин


person maasha    schedule 22.05.2011    source источник
comment
Спасибо :о). Я узнал, насколько изящный этот форум от biostars.org.   -  person maasha    schedule 22.05.2011


Ответы (1)


Загрузить данные из STDIN во временный файл и только потом парсить его

require 'tempfile'

tf = Tempfile.new('tmp')

while $stdin.gets do
   tf.puts $_
end

tf.rewind
person Troydm    schedule 22.05.2011
comment
Я работаю с довольно большим количеством данных и хотел бы избежать временного решения для файлов. Мне кажется, что GzipReader должен прочитать кусок данных в буфере и распаковать его, если это возможно, или вызвать ошибку. GzipReader должен иметь какой-то метод для проверки того, содержит ли буфер заархивированные данные, или возвращать буфер как объект ввода-вывода. - person maasha; 22.05.2011