![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
TCompressionStream не возвращает поток в TMemoryStream - почему?
koha © (2007-05-17 13:23:00)TCompressionStream не возвращает поток в TMemoryStream - почему?
Хочу написать функцию: CompressStrToStr(StrInp: String): String; , которая на входе принимала строку несжатую на выходе давала сжатую строку. Проблема в том, что использовал поток приемник TMemoryStream, но почему то TCompressionStream ни чего в него не пишет, а если взять TFileStream в место TMemoryStream, то пищет.
Можно ли какую-нибудь штуку придумать за место TFileStream но только в память?
Сергей М. (2007-05-17 15:31:00) [1]
> koha © (17.05.07 15:24) [10]
Но тут единственное ограничение - невозможность задать уровень компрессии.
Но и его можно обойти, скопировав код ф-ции CompressBuf (и еще минимально необходимые куски кода, от которых зависит работа этой ф-ции) в код своего приложения и подправить как нужно.
koha (2007-05-17 15:24:00) [2]> [9] Сергей М. © (17.05.07 14:40)
Да и вообще - нет никакого резона заморачиваться именно со стримами, если все гораздо проще:
- И то правильно. Как же я сразу не догнал.
Сергей М. (2007-05-17 14:40:00) [3]Да и вообще - нет никакого резона заморачиваться именно со стримами, если все гораздо проще:
Function CompressStrToStr(StrInp: String; ALevel: TCompressionLevel): String;
var
OutBuf: Pointer;
OutSize: Integer;
begin
CompressBuf(PChar(StrInp), Length(StrInp), OutBuf, OutSize);
if OutSize > 0 then
try
SetLength(Result, OutSize);
Move(OutBuf, PChar(Result)^, OutSize);
finally
FreeMem(OutBuf);
end;
end;
Сергей М. (2007-05-17 14:29:00) [4]Function CompressStrToStr(StrInp: String; ALevel: TCompressionLevel): String;
Var
OutStrm : TMemoryStream;
CompStrm : TCompressionStream;
Count : Integer;
begin
OutStrm := TMemoryStream.Create;
CompStrm := TCompressionStream.Create(ALevel, OutStrm);
try
CompStrm.WriteBuffer(StrInp[1],Length(StrInp));
if OutStrm.Size > 0 then begin
SetLength(Result, OutStrm.Size);
Move(OutStrm.Memory^, PChar(Result)^, OutStrm.Size);
end;
finally
CompStrm.Free;
OutStrm.Free;
end;
end;
koha (2007-05-17 14:29:00) [5]- дело в том, что OutStrm.Size всегда остается в нулевом состоянии так же как и OutStrm.Position
koha (2007-05-17 14:27:00) [6]> [5] MBo © (17.05.07 14:19)
> А где задается размер выходной строки?
Эту строчку я пропустил, просто забыл когда писал, но всего скорей после этой строки:
//..........
Count:=CompStrm.Write(StrInp[1],Length(StrInp));
If Count = 0 then exit;
if OutStrm.Size = 0 then exit;
SetLength(Result,OutStrm.Size);
//........................
MBo (2007-05-17 14:19:00) [7]А где задается размер выходной строки?
koha (2007-05-17 14:05:00) [8]- Я так думаю, что это наверно проблема в том, что для TMemoryStream не определен размер буфера, т.е. не выделена память или я ошибаюсь? Но ведь заранее как узнать, что вернет TCompressionStream?
koha (2007-05-17 13:57:00) [9]
Function CompressStrToStr(StrInp: String; N: Integer): String;
Var
OutStrm : TMemoryStream;
CompStrm : TCompressionStream;
Count : Integer;
begin
if N > 3 then N:=3; // Степень сжатия
if N < 0 then N:=0;
OutStrm := TMemoryStream.Create;
CompStrm := TCompressionStream.Create(TCompressionLevel(N),OutStrm);
try
Count:=CompStrm.Write(StrInp[1],Length(StrInp));
If Count = 0 then exit;
OutStrm.Seek(0,soFromBeginning);
OutStrm.Read(Result[1],OutStrm.Size);
finally
CompStrm.Free;
OutStrm.Free;
end;
end;
Reindeer Moss Eater (2007-05-17 13:54:00) [10]но почему то TCompressionStream ни чего в него не пишет, а если взять TFileStream в место TMemoryStream, то пищет.
Это еще один "оптический обман".
Сергей М. (2007-05-17 13:42:00) [11]Показывай код ..