Почему при использовании unix-compress и go compress/lzw создаются разные файлы, которые не читаются другим декодером?
Я сжал файл в терминале с compress file.txt
и получил (как и ожидалось) file.txt.Z
Когда я передаю этот файл ioutil.ReadFile
на ходу,
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 кБ, сжатый unix file.txt.Z
составляет 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 будет принимать только файлы, сжатые с помощью Go compress/lzw
,
Может кто-нибудь объяснить, почему это произошло? Почему два файла.Z не эквивалентны? Как я могу преодолеть это?
Примечание: я работаю на Ubuntu, установленном в VirtualBox на Mac.
2 ответа
Файл.Z содержит не только сжатые данные LZW, но также имеется 3-байтовый заголовок, который не генерируется кодом Go LZW, поскольку он предназначен для сжатия данных, а не для создания файла Z.
Предположительно, вы хотите протестировать производительность только двух ваших / некоторых сторонних алгоритмов (а не самих алгоритмов сжатия), вы можете написать сценарий оболочки, который вызывает команду сжатия, передающую необходимые файлы / каталоги, и затем вызывает этот сценарий. из вашей программы C / GO. Это один из способов, с помощью которого вы можете преодолеть это, но оставляете открытыми другие части ваших запросов о правильном использовании библиотек сжатия.
За этим вопросом скрывается древняя ошибка "группы битов выравнивания". Я описал это в википедии "Особый выходной формат". Пожалуйста прочти.
Я реализовал новую библиотеку lzws. В нем есть все возможные варианты:
--without-magic-header
(-w
) - отключить магический заголовок--max-code-bit-length
(-b
) - установить максимальную длину кода в битах (9-16)--raw
(-r
) - отключить режим блокировки--msb
(-m
) - включить старший бит--unaligned-bit-groups
(-u
) - включить невыровненные битовые группы
Вы можете использовать любые варианты во всех возможных комбинациях. Все комбинации проверены. Уверен, что можно найти комбинации, подходящие для реализации go lzw.
Вы можете использовать привязку ruby-lzws, если хотите использовать ruby.