Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сжатие потока, Как сжать/расжать поточные данные? 
:(
    Опции темы
WolfAlone
Дата 24.3.2012, 20:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


В экстазе
***


Профиль
Группа: Завсегдатай
Сообщений: 1010
Регистрация: 16.9.2008
Где: Рай

Репутация: нет
Всего: 5



Доброго времени суток!

Помогите пожалуйста решить следующую задачу:
Имеется некоторый поток в памяти (TMemoryStream), в котором содержиться, некоторые данные, достуим строка "AAAAAAAAAA". Необходимо сжать данные в этом потоке, и полученный результат (после сжатия) пометстить в другой поток (TMemoryStream). Чем (каким алгоритмом) сжимать/разживать значения не имеет. ZIP, GZip и т.п. - не принципиально вообще. Главное, провести процедулу "архивации" над данными в памяти и полученный результат записать в другой поток, для возможности дальнейших манипуляций с ним.

В идеале -  хотелось бы найти готовый модуль или библиотеку, для подключения в программу с целью дальнейшего использования, т.к. используется Turbo C++ Explorer, который не подразумевает установку каких-либо стронних компонентов.

Подскажите пожалуйста, возможные решения.


--------------------
И сказал Бог: "Тогда я построю свой мир с блэк-джеком и шлюхами!"

Ф топку Ubuntu, Debian наше фсё!

(с) Евгений Вольф
PM MAIL WWW ICQ Skype   Вверх
Alexeis
Дата 24.3.2012, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Стандартный класс TCompressionStream


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
WolfAlone
Дата 24.3.2012, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


В экстазе
***


Профиль
Группа: Завсегдатай
Сообщений: 1010
Регистрация: 16.9.2008
Где: Рай

Репутация: нет
Всего: 5



Alexeis, судя по всему, TCompressionStream работает исключительно с файловыми потоками и никоим образом не хочет паковать "память"...

Это сообщение отредактировал(а) WolfAlone - 25.3.2012, 00:16


--------------------
И сказал Бог: "Тогда я построю свой мир с блэк-джеком и шлюхами!"

Ф топку Ubuntu, Debian наше фсё!

(с) Евгений Вольф
PM MAIL WWW ICQ Skype   Вверх
Alexeis
Дата 24.3.2012, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Цитата(WolfAlone @  24.3.2012,  22:32 Найти цитируемый пост)
судя по всему, 

А судя по документации 
Код

__fastcall TZCompressionStream(System::Classes::TStream* dest)

нет, и судя по опыту тоже нет. Работает с любыми потоками. Просто внимательно нужно посмотреть что куда передавать и сдвигать указатель на данные в ноль. Некоторые операции производятся от текущей позиции в памяти.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
WolfAlone
Дата 25.3.2012, 00:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


В экстазе
***


Профиль
Группа: Завсегдатай
Сообщений: 1010
Регистрация: 16.9.2008
Где: Рай

Репутация: нет
Всего: 5



Подскажите пожалуйста, почему при использовании TCompressionStream, при сжатии маленьких файлов (точно размер файла, который можно назвать "маленьким" сказать не могу) - результат сжатия поток размером в 0 байт, а при сжатии больших файлов - всё работает нормально?

Подробности:
Для тестов, взял копии тех файлов, что лежат в папке: "Debug_build", в частности, следующие файлы (их копии! блокировки на чтение нет!)
1. "Маленький файл": "project.obj", размер: 52Кб
2. "Большой файл": "project.tds", размер около 3.5Мб

Я долго и упорно искал свою ошибку, но потом пришел к выводу, что кроме имени файла, я в коде не меняю ничего, а результат абсолютно разный. А именно:
При сжатии "маленького файла", выходной файл получается 0 байт, при сжатии "большого файла", выходной файл получается: ~800Кб.

Вообще, операции должны проходить над данными в TMemoryStream, но в целях отладки (тестов), я копирую в TMemoryStream данные из TFileStream.

Собственно, код:

Код

    TFileStream* f_in = new TFileStream("to_zip.obj", fmOpenRead);
    TFileStream* f_out = new TFileStream("file_out", fmOpenWrite|fmCreate);

    TMemoryStream* ms_in = new TMemoryStream();
    TMemoryStream* ms_out = new TMemoryStream();


    TCompressionStream* cmp = new TCompressionStream(Zlib::clMax, ms_out);
    f_in->Seek(0, 0);
    ms_in->CopyFrom(f_in, f_in->Size);
    ms_in->Seek(0, 0);
    cmp->CopyFrom(ms_in, ms_in->Size);
    ms_out->Seek(0, 0);
    f_out->CopyFrom(ms_out, ms_out->Size);


Это сообщение отредактировал(а) WolfAlone - 25.3.2012, 01:27


--------------------
И сказал Бог: "Тогда я построю свой мир с блэк-джеком и шлюхами!"

Ф топку Ubuntu, Debian наше фсё!

(с) Евгений Вольф
PM MAIL WWW ICQ Skype   Вверх
Alexeis
Дата 25.3.2012, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Цитата(WolfAlone @  25.3.2012,  01:30 Найти цитируемый пост)
При сжатии "маленького файла", выходной файл получается 0 байт, при сжатии "большого файла", выходной файл получается: ~800Кб.

  Дело в буферизации. Маленькие объемы не пожмутся сразу.
Код

    Classes::TStream   *comprdata  = new TMemoryStream;
    TCompressionStream *compressor = new TCompressionStream(Zlib::clMax, comprdata);

    wchar_t str1[] = L"ляя ля ля жу жу жу всякую фигню пожму";
    int res_size = compressor->Write(str1, sizeof(str1));
    delete compressor;

    res_size = comprdata->Size;

После delete compressor; все данные успешно пожались и перешли в comprdata  .


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
WolfAlone
Дата 26.3.2012, 00:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


В экстазе
***


Профиль
Группа: Завсегдатай
Сообщений: 1010
Регистрация: 16.9.2008
Где: Рай

Репутация: нет
Всего: 5



Alexeis, как-то я над этим не подумал... Спасибо огромное! Остались последние штрихи.

Подскажите пожалуйста, есть ли какой-то способ сбросить буфер без удаления самого потока? Перерыл всю справку, что-то наподобии flush();, так и не нашёл.

И самое главное - нигде не могу найти пример, как обработать т.н. "прогресс", то есть, как повесить обработчик на событие TCompressionStream::OnProgress. Перерыл весь интернет, справку и всё, что попадало под руку. Примеры либо для Delphi, либо их нет вообще... Даже Google молчит! Подскажите пожалуйста, простейший пример обработки этого события?


--------------------
И сказал Бог: "Тогда я построю свой мир с блэк-джеком и шлюхами!"

Ф топку Ubuntu, Debian наше фсё!

(с) Евгений Вольф
PM MAIL WWW ICQ Skype   Вверх
Alexeis
Дата 26.3.2012, 19:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 26
Всего: 459



Цитата(WolfAlone @  26.3.2012,  01:34 Найти цитируемый пост)
Подскажите пожалуйста, есть ли какой-то способ сбросить буфер без удаления самого потока? Перерыл всю справку, что-то наподобии flush();, так и не нашёл.

  Нету там такого, только если унаследовать класс и вызывать функцию deflate руками задав параметр сжать без кеша. 
Код

const
  {** flush constants *******************************************************}

  Z_NO_FLUSH = 0;
  Z_PARTIAL_FLUSH = 1;
  Z_SYNC_FLUSH = 2;
  Z_FULL_FLUSH = 3;
  Z_FINISH = 4;

В классе вызывается deflate с параметром Z_NO_FLUSH, т.е. по умолчанию кэширование. Вероятно нужно вызвать с параметром Z_FULL_FLUSH .

На счет прогресса тут видимо нужно следить за изменением позиции в потока куда сливаются данные.
Код

function TZCompressionStream.Write(const buffer; count: Longint): Longint;
begin
  FZStream.next_in := @buffer;
  FZStream.avail_in := count;

  if FStream.Position <> FStreamPos then FStream.Position := FStreamPos;

  while FZStream.avail_in > 0 do
  begin
    ZCompressCheck(deflate(FZStream, Z_NO_FLUSH));

    if FZStream.avail_out = 0 then
    begin
      FStream.WriteBuffer(FBuffer, SizeOf(FBuffer));

      FZStream.next_out := FBuffer;
      FZStream.avail_out := SizeOf(FBuffer);

      FStreamPos := FStream.Position;

      DoProgress;
    end;
  end;

  result := Count;
end;

раз авторы кода считывают  FStreamPos := FStream.Position; , то вероятно оно меняется после каждой операции сжатия.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0552 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.