Как мне записать прикрепленный ZIP-файл к файлу с Ruby File.new?

Я подключаюсь к серверу IMAP и загружаю сообщение с вложением ZIP. Я запускаю свой сценарий как на локальной, так и на удаленной машине. Я могу правильно сохранить файл на обеих машинах, но по какой-то причине я получаю ошибки при распаковке на удаленном компьютере.

Мой рубиновый код, который сохраняет вложение zip:

attachment = imap.fetch(message_id, "BODY[2]")[0].attr["BODY[2]"]
save_path = "#{save_path_base}/#{fname}"
File.new(save_path, "wb+").write(attachment.unpack("m"))

На моем локальном компьютере (OS X) запуск unzip file.zip с файлом работает отлично, но на удаленном компьютере (CentOS) та же команда выдает ошибку:

Подпись конца центрального каталога не найдена. Либо этот файл не является zip-файлом, либо он составляет один диск многосоставного архива. В последнем случае центральный каталог и комментарий к zip-файлу будут найдены на последнем диске (ах) этого архива.

Что могло привести к правильному сохранению файла на моем локальном компьютере и повреждению на удаленном компьютере? Или моя локальная распаковка игнорирует ошибки? На обеих машинах unzip указывает на /usr/bin/unzip.

РЕДАКТИРОВАТЬ:

На моем локальном компьютере file file.zip предоставляет мне данные архива Zip, по крайней мере v2.0 для извлечения. Моя локальная версия Ruby - ruby 1.8.7 (2012-02-08 patchlevel 358)

На моем удаленном сервере команда возвращает текст ASCII с очень длинными строками без разделителей строк. Моя удаленная версия Ruby - ruby 2.0.0p647 (2015-08-18)

Как убедиться, что файл распознан как ZIP на удаленном компьютере?

РЕДАКТИРОВАТЬ: решение добавлено ниже в качестве ответа


person juuga    schedule 04.11.2015    source источник
comment
Вы должны опубликовать свое решение как ответ на свой вопрос, а затем принять его.   -  person Mark Reed    schedule 04.11.2015


Ответы (1)


Решением, конечно же, было выяснить, что изменилось между версиями Ruby. В этой ветке указывается, что:

В 1.8 это эквивалентно вызову join, в 1.9 это эквивалентно вызову inspect. Чтобы добиться желаемого поведения как в 1.8, так и в 1.9, вызовите join вместо to_s.

Итак, решение заключалось в том, чтобы изменить строку на

File.new(save_path, "wb+").write(attachment.unpack("m").join)

Потому что по умолчанию write вызывает to_s, если указано что-то помимо строки.

person juuga    schedule 04.11.2015