Почему использование unix-compress и go compress/lzw создает разные файлы, не читаемые другим декодером?

Я сжал файл в терминале с помощью compress file.txt и получил (как и ожидалось) file.txt.Z

Когда я передаю этот файл ioutil.ReadFile в Go,

buf0, err := ioutil.ReadFile("file.txt.Z")

Я получаю сообщение об ошибке (строка выше 116):

finder_test.go:116: lzw: invalid code

Я обнаружил, что Go примет файл, если я сожму его с помощью пакета compress/lzw, я просто использовал код из веб-сайт, который это делает. Я только изменил строку

outputFile, err := os.Create("file.txt.lzw")

Я изменил .lzw на .Z. затем использовал полученный file.txt.Z в коде Go вверху, и он работал нормально, без ошибок.

Примечание. file.txt составляет 16,0 КБ, file.txt.Z в unix-сжатии — 7,8 КБ, а file.txt.Z в сжатом виде — 8,2 КБ.

Теперь я пытался понять, почему это произошло. Итак, я попытался запустить

uncompress.real file.txt.Z

и это не сработало. я получил

file.txt.Z: not in compressed format

Мне нужно использовать компрессор (предпочтительно unix-compress) для сжатия файлов с помощью lzw-compression, а затем использовать те же сжатые файлы на двух разных алгоритмах, один написан на C, а другой на Go, потому что я намерен сравнить производительность двух алгоритмов. Программа C будет принимать только файлы, сжатые с помощью unix-compress, а программа Go будет принимать только файлы, сжатые с помощью compress/lzw Go.

Кто-нибудь может объяснить, почему это произошло? Почему два файла .Z не эквивалентны? Как я могу преодолеть это?

Примечание. Я работаю над Ubuntu, установленной в VirtualBox на Mac.


person Maryam AbuShaaban    schedule 19.03.2017    source источник


Ответы (3)


Файл .Z содержит не только сжатые данные LZW, но и 3-байтовый заголовок. который код Go LZW не генерирует, потому что он предназначен для сжатия данных, а не для создания Z-файла.

person Zoyd    schedule 19.03.2017
comment
Или, может быть, разумнее было бы просто прочитать файл .Z, сжатый unix, в Go и просто опустить первые 3 байта. Я прав? - person Maryam AbuShaaban; 19.03.2017
comment
Один из таких, да. Затем на той же странице также предлагается использовать для сжатия пользовательскую версию LZW, поэтому этого может быть недостаточно. В этом случае вы можете поэкспериментировать с файлами GIF. - person Zoyd; 19.03.2017
comment
В статье об одном из алгоритмов, которые я использую, они используют unix-compress , так что я буду использовать его. Очень полезно, спасибо! - person Maryam AbuShaaban; 19.03.2017
comment
после этой строки buf0, err := ioutil.ReadFile("file.txt.Z") я взял фрагмент из я сделал buf3 := buf0[3:], а затем вместо этого использовал фрагмент buf3. Это все еще дает мне ту же ошибку - person Maryam AbuShaaban; 20.03.2017
comment
Как я уже писал выше, на странице, на которую я дал ссылку, указано, что сжатие использует пользовательскую версию LZW, которая может быть несовместима с реализацией Go. - person Zoyd; 20.03.2017
comment
О да, теперь это имеет смысл. Я пытаюсь найти способ изменить код Go для чтения LZC-варианта LZW. - person Maryam AbuShaaban; 20.03.2017

Предположительно, вы хотите проверить производительность только двух ваших/некоторых сторонних алгоритмов (а не самих алгоритмов сжатия), вы можете написать сценарий оболочки, который вызывает команду сжатия, передавая необходимые файлы/каталоги, а затем вызывает этот сценарий из вашей программы C/GO. Это один из способов преодолеть это, но оставляет открытыми другие части ваших запросов о правильном способе использования библиотек сжатия.

person Ravi    schedule 20.03.2017

За этим вопросом стоит древняя ошибка под названием "группы битов выравнивания". Я описал это в википедии "Специальный формат вывода". Пожалуйста, прочитайте.

Я реализовал новую библиотеку lzws. У него есть все возможные варианты:

  1. --without-magic-header (-w) - отключить магический заголовок
  2. --max-code-bit-length (-b) - установить максимальную длину кода в битах (9-16)
  3. --raw (-r) - отключить блочный режим
  4. --msb (-m) - включить старший бит
  5. --unaligned-bit-groups (-u) - включить невыровненные битовые группы

Вы можете использовать любые опции во всех возможных комбинациях. Все комбинации проверены. Я уверен, что вы можете найти комбинации, подходящие для реализации go lzw.

Вы можете использовать привязку ruby-lzws, если хотите использовать ruby.

person puchu    schedule 17.04.2020