|
Модераторы: Poseidon, Snowy, bems, MetalFan |
|
atr |
|
||||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 3.5.2006 Репутация: нет Всего: нет |
Добрый день!
Prehistory Пришёл я на работу в контору, с почти готовым продуктом. По ходу процесса нужно хранить отчёты (FastReport 3) в БД (Firebird). Всё в общем работает, но размеры базы перевалили за 1.5 гига за 4 месяца. Попытка Решил я жать готовый отчёт при записи в базу и расжимать при чтении. Написал для сжатия следующее:
Базу забэкапил - восстановил - 220 Мб. На первый взгляд, при просмотре BLOB поля где хранятся отчёты типичная картина жатых данных. Решил восстановить из поля отчёт и показать
Не подскажите ли что сделал неверно. Ни разу, до сих пор не работал с ZLib, похоже не понял идеологию. Спасибо. |
||||
|
|||||
Snowy |
|
|||
Эксперт Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
Нет. Так с ZLib работать нельзя. Стримы ZLib'a не являются полноценными стримами.
Поэтому для корректной работы создай 2 мемористрима. А ZLib используй, как посредника между ними. Для перегона из одного стрима в другой, воспользуйся этим модулем: http://forum.vingrad.ru/index.php?showtopi...st&p=620614 |
|||
|
||||
atr |
|
|||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 3.5.2006 Репутация: нет Всего: нет |
Посмотрел, идея ясна.
size:dword используется как буфер в Decompress.Create? ... и ещё - процесс сжатия я правильно сделал? Это сообщение отредактировал(а) atr - 3.5.2006, 12:39 |
|||
|
||||
Snowy |
|
|||
Эксперт Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
Нет. Он сохраняет размер исходного стрима. Не зная этот размер, распаковать невозможно.
Соответственно нет - нужно сохранять размер. Ну и компрессию можно было посильнее установить (clMax). |
|||
|
||||
atr |
|
||||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 3.5.2006 Репутация: нет Всего: нет |
Хм...
Меня терзают смутные сомненья:
В то же время
строка cs.Read(size,SizeOf(Size)); более чем непонятна... (уж простите за дремучесть ) Добавлено @ 13:16 Ой... смысл вродь такой, перед жатием в стрим пишем размер нежатых данных, а при декомпрессии читаем этот размер, так чтоль? |
||||
|
|||||
Alexeis |
|
|||
Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
Чтение из потока в переменную, SizeOf даст нам число байт или размер переменной. Прочитав правельный размер данных (хранится в size) мы можем их извлечь из потока. Добавлено @ 13:17
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Snowy |
|
|||
Эксперт Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 192 Всего: 484 |
А тут все просто.
Size имеет тип DWORD. 4 байта. В них хранится размер несжатого стрима. В данной строке мы говорим - прочитай в переменную Size данные, размеров SizeOf(Size) - 4 байта. Можно было просто написать cs.Read(size, 4);, но правила хорошего тона говорят о необходимости использования SizeOf. Вдруг мы захотим изменить тип Size на word или Int64... |
|||
|
||||
atr |
|
|||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 3.5.2006 Репутация: нет Всего: нет |
Snowy, alexeis1 - спасибо! Теперь вродь всё ясно. Сейчас пережму данные уже с открытыми глазами
Тему пока не закрываю, вдруг что.... Я использую ZLibEx, но различий принципиальных с ZLib в технологии похоже нет. |
|||
|
||||
atr |
|
||||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 3.5.2006 Репутация: нет Всего: нет |
Переделал сжатие:
Сделал чтение данных и декомпрессию:
При пошаговопроходе видно, что при создании потока Z получаем исходный размер нежатых данных + 8 байт на размер (Int64). Правильно считывается Z.Read(size,SizeOf(size)). А в строке d.CopyFrom(Z,Size); выскакивает ошибка "Stream read error". Ведь всё кажись правильно сделал. Не хватает буквально какойто мелочи до получения результата. Абыдна, да... |
||||
|
|||||
atr |
|
|||
Новичок Профиль Группа: Участник Сообщений: 6 Регистрация: 3.5.2006 Репутация: нет Всего: нет |
Всё работает!
17 строка, там где пусто добавить D.Position:=0 и всё нормально. Храните отчёты в своих базах в сжатом виде! |
|||
|
||||
darweeng |
|
||||
Новичок Профиль Группа: Участник Сообщений: 3 Регистрация: 29.12.2012 Репутация: нет Всего: нет |
Доброго времени! Никак не могу перевести в С++ строку №14 из последнего примера:
В Билдере выходит так
что надо писать в скобках? |
||||
|
|||||
Alexeis |
|
|||
Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 109 Всего: 459 |
В Билдере там void* , принимает указать на область памяти куда будут записаны данные. В делфи там переменная которая принимается по ссылке. В переменную size типа integer записывается размер чего-то там .
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Правила форума "Delphi: Общие вопросы" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |