![]() |
|
Модераторы: LSD, AntonSaburov |
![]()
|
|
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Я тут пытался реализовать метод сжатия LZ78 на моем любимом Java. Вроде все понятно, но проблемы, кажется, с сохранением в файл. Наверное, проблемы с переводом из класса Record в строку и обратно. Напомню людям, что каждая запись содержит номер записи, с которой начинается данная и символ, который к ней дописывается. Запись состоит из одного чара и 1-го int'а. Как понимаете, int в файл может записываться с разной длиной, а мне надо с фиксированой. Я выбрал 2 байта. Вот код:
Код работает для ультра-коротких файлов, и дает сбои со сравнительно средними файлами. Вероятно, это происходит из-за увеличения размера словаря. Если не сохранять в файл и раскодировать сразу из values, то все прекрасно для всех файлов умеренных размеров, а вот раскодировать архив уже не получается. |
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
С LZ78 я незнаком, поэтому пока объясни поподробней, что именно там происходит.
Дело в том, что char это UTF-16, он хранит 65536 различных символов. А запись в файл идет в системной кодировке, как правило это однобайтовые кодировки, т.е. 256 символов. И подобное преобразование конечно не может пройти без потерь. Так что сам принцип сохранения не верен. -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
| jimur |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 21.4.2006 Репутация: 2 Всего: 3 |
А out.flush() не пробовал ставить?
|
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
-------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
| jimur |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 21.4.2006 Репутация: 2 Всего: 3 |
||||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Не понял. Ты предлагаешь вызвать именно flushBuffer() вместо flush()?
И чем это поможет, если перед закрытием буффер все равно очищается? -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
| jimur |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 21.4.2006 Репутация: 2 Всего: 3 |
Предлагаю попробовать вызывать
вместо out.close(); вызывать out.flush(); out.close(); выдержка из исходников в сочетании с приведенными выше фрагментами объясняет почему
|
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Ээээ, люди со flush() и close() все отлично, дело в другом.
LSD, значит с байтами. А я чего-то не пойму, ведь смотрю в архивный файл и вижу все нормально: 1 байт под символ, 2 байта под int. И как-бы чары и без этого жмутся в 1 байт. А с байтами очень уж неудобно работать. Ну, это не очень важно, но если требуешь попробую объяснить: В общем начинаем. Фраза, записываемая в файл, будет состоять из 3-х байт: 1 под символ, 2 под число. В методе есть строчный вектор словарь и фразный вектор значения. Каждый цикл считываем по 1-му чару. И прибавляем его к исследуемой строке curString. Ищем эту строку в словаре, если она есть, то запоминаем номер ее позиции, если нет, надо занести в словарь и добавить новую запись с последним прочитанным символом и позицией последней совпавшей строки. Фу... вроде ничего не упустил, правда пока не проверял, но хвост может оставаться, я там такую пришпандорку сделал. Прошу прощения за бестактный вопрос, но как байты то в BufferedWriter записывать? Это сообщение отредактировал(а) Platon - 26.4.2006, 17:42 |
|||
|
||||
| jimur |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 21.4.2006 Репутация: 2 Всего: 3 |
||||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Так. Я выяснил в чем ошибка. Проблема в том, что выражение return new Record(str[0], ((int)str[1] << 8) | str[2]); работает некорректно.
В случае когда int равен 128 оно естественно представляется в виде 0x0080 в двухбайтной системе. Хе а когда обратно перевожу у меня два байта один равен нулю, а второй -128, второй приводится к int, причем знак сохраняется!!! И получается все равно -128 вместо 128. Козалось бы чего сложного. В С++ это решается просто, а в Java как? Это сообщение отредактировал(а) Platon - 26.4.2006, 17:25 |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Тупейшим образом решил свою проблему:
Как проще-то? |
|||
|
||||
| LSD |
|
|||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Вовсе не объясняет (а исходники я и так видел). close() вызывает очистку данного буфера, и закрытие нижележащего потока, который в свою очередь сам очистит свой буфер перед закрытием. В Java char - это 2 байта, а int - 4 байта. Зачем тебе вообще нужны char, почему ты не работаешь с byte, что в них такого сложного? -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
|||
|
||||
| jimur |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 73 Регистрация: 21.4.2006 Репутация: 2 Всего: 3 |
||||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
LSD, да согласен уже перешел. Но загвоздка в переводе 2-х байтов в int. Я решил ее одним методом, но уж больно кривенький он. Неужели в Java нет unsigned byte?
Добавлено @ 08:15 И еще. Можно ли порции битов из файла читать? Или свой класс разрабатывать? |
|||
|
||||
| batigoal |
|
|||
![]() Нелетучий Мыш ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 6423 Регистрация: 28.12.2004 Где: Санктъ-Петербургъ Репутация: 24 Всего: 151 |
-------------------- "Чтобы правильно задать вопрос, нужно знать большую часть ответа" (Р. Шекли) ЖоржЖЖ |
|||
|
||||
| Platon |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1801 Регистрация: 25.4.2006 Репутация: 16 Всего: 40 |
Lamer George, и что? Мне в таком же духе продолжать?
|
|||
|
||||
| LSD |
|
||||||||
![]() Leprechaun Software Developer ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 15718 Регистрация: 24.3.2004 Где: Dublin Репутация: 210 Всего: 538 |
Очень странный код... 1. Ты делаешь из byte - char, при этом расширение будет знаковое. Т.е. для ASCII кодов (0-127) у тебя будет вполне осмысленный результат. А вот для кодов более 127 будет фигня, например byte - 0xFF, будет преобразован в char - \uFFF3 - которй вообще непонятно какой символ дает. char - предназначен для хранения символов, если тебе нужно читать символы из файла используй CharsetDecoder. А если нет, то используй просто byte, short или int. 2. Затем вот эта странная конструкция:
ее смысл я вообще не понял. Если тебе надо прочитать байты в int то делай так:
для big-endian и
для little-endian -------------------- Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it. |
||||||||
|
|||||||||
![]()
|
| Правила форума "Java" | |
|
|
Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Java: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |