![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Модуль Compress.pas - распаковка ресурсов в файл
koha © (2007-01-08 02:23:00)Вот на скорую руку модуль состряпал для запаковки / файлов на основе Zlib, так же для Распаковки Встроенных ресурсов в файл.
Кто, что подскажет для лучшей работы и исправления ляпусов ? А так вроде работает.
unit Compress;
interface
Uses Classes, Windows, SysUtils, ZLib;
Function CompressFile(InpFile: String; OutFile: String; N: Integer): boolean;
Function DecompressFile(InpFile: String; OutFile: String): boolean;
Function DecompressResToFile(ResName: String; FileName: String): Boolean;
Var
INP_STRM, OUT_STRM : TFileStream;
RES_STRM : TResourceStream;
COMPRESS_STRM : TCompressionStream;
DECOMPRESS_STRM : TDecompressionStream;
implementation
Function CompressFile(InpFile: String; OutFile: String; N: Integer): boolean;
Var
FBuffer: Array[0..1023] of char;
ByteRaed: Integer;
Begin
try
try
INP_STRM := TFileStream.Create(InpFile,fmOpenRead);
OUT_STRM := TFileStream.Create(OutFile,fmCreate);
COMPRESS_STRM := TCompressionStream.Create(clMax,OUT_STRM);
repeat
ByteRaed := INP_STRM.Read(FBuffer,SizeOf(FBuffer));
COMPRESS_STRM.Write(FBuffer,ByteRaed);
until ByteRaed < 1024;
Result:=True;
finally
COMPRESS_STRM.Free;
INP_STRM.Free;
OUT_STRM.Free;
for ByteRaed:=0 to 1023 do FBuffer[ByteRaed]:=#0;
end;
Except
Result:=False;
COMPRESS_STRM.Free;
INP_STRM.Free;
OUT_STRM.Free;
for ByteRaed:=0 to 1023 do FBuffer[ByteRaed]:=#0;
end;
end;
Function DecompressFile(InpFile: String; OutFile: String): boolean;
Var
Buffer: Array[0..1023] of char;
ByteRaed: Integer;
Begin
try
try
INP_STRM := TFileStream.Create(InpFile,fmOpenRead);
OUT_STRM := TFileStream.Create(OutFile,fmCreate);
DECOMPRESS_STRM := TDecompressionStream.Create(OUT_STRM);
repeat
ByteRaed := INP_STRM.Read(Buffer,SizeOf(Buffer));
DECOMPRESS_STRM.Write(Buffer,ByteRaed);
until ByteRaed < 1024;
Result:=True;
finally
DECOMPRESS_STRM.Free;
INP_STRM.Free;
OUT_STRM.Free;
for ByteRaed:=0 to 1023 do Buffer[ByteRaed]:=#0;
end;
Except
Result:=False;
DECOMPRESS_STRM.Free;
INP_STRM.Free;
OUT_STRM.Free;
for ByteRaed:=0 to 1023 do Buffer[ByteRaed]:=#0;
end;
end;
Function DecompressResToFile(ResName: String; FileName: String): Boolean;
Var
Buffer: Array[0..1023] of char;
ByteRaed: Integer;
Begin
Try
Try
RES_STRM := TResourceStream.Create(HInstance,ResName,RT_RCDATA);
OUT_STRM := TFileStream.Create(FileName,fmCreate);
DECOMPRESS_STRM := TDecompressionStream.Create(RES_STRM);
repeat
ByteRaed:=DECOMPRESS_STRM.Read(Buffer,SizeOf(Buffer));
OUT_STRM.Write(Buffer,ByteRaed);
until ByteRaed < 1024;
Result:=true;
finally
DECOMPRESS_STRM.Free;
RES_STRM.Free;
OUT_STRM.Free;
for ByteRaed:=0 to 1023 do Buffer[ByteRaed]:=#0;
end;
except
DECOMPRESS_STRM.Free;
RES_STRM.Free;
OUT_STRM.Free;
for ByteRaed:=0 to 1023 do Buffer[ByteRaed]:=#0;
Result:=false;
end;
end;
end.
koha (2007-01-08 07:56:00) [1]- в этом немного разобрался ведь по сути теперь особой разницы не видать как обработку ошибок вести или внутри функции или снаружи, я думаю это наверное зависить будет от того в каком месте программы функцию использовать. Меня так устраивает и такой вариант:
function();
try
//..........
result:=true;
except MessageDlg(); end;
//........
end;
Вот еще осталось написать пару функций, довольно актуальных, которые при помощи Zlib сжимали и расжимали данные перед и после отправки пакетов по сети.
Дописать утилиту, которая будет готовить из файлов сжатые ресурсы и выложить на свой сайт и будет все шоколаде шоколаде.
Anatoly Podgoretsky (2007-01-08 07:29:00) [2]> koha (08.01.2007 07:19:21) [21]
Именно это тебе и предлагали, это более гибко.
koha (2007-01-08 07:19:00) [3]> app © (08.01.07 07:07) [20]
> Убери совсем except и далее смотри [17] и далее.
- в таком случае предлагается наверное это:
try
Myfunction();
except //....... end;
app (2007-01-08 07:07:00) [4]
> Тогда закономерный вопрос : как проконтролировать выполнение
> и не выполение функции?
Убери совсем except и далее смотри [17] и далее.
Джо (2007-01-08 06:39:00) [5]> [18] koha © (08.01.07 06:35)
> > Если не произошло исключения, значит процедура выполнилась
> успешно
>
> - вот именно этой процедуре, извеняюсь, т.е. функции можетбыть
> и вовсе нестоит быть функцией?
Может, и не стоит. По крайней мере, в таком варианте, когда на любую ошибку возвращается просто False, а не причина ошибки. Особого смысла в этом нет.
koha (2007-01-08 06:35:00) [6]> Если не произошло исключения, значит процедуравыполнилась успешно
- вот именно этой процедуре, извеняюсь, т.е. функции можетбыть и вовсе нестоит быть функцией?
Джо (2007-01-08 04:56:00) [7]> [16] koha © (08.01.07 04:41)
> > Джо © (08.01.07 04:07) [14]
> > Германн © (08.01.07 04:21) [15]
>
> - Тогда закономерный вопрос : как проконтролировать выполнение
> и не выполение функции?
Если не произошло исключения, значит процедура выполнилась успешно.
koha (2007-01-08 04:41:00) [8]> Джо © (08.01.07 04:07) [14]
> Германн © (08.01.07 04:21) [15]
- Тогда закономерный вопрос : как проконтролировать выполнение и не выполение функции?
Германн (2007-01-08 04:21:00) [9]Добавлю к
> Джо © (08.01.07 04:07) [14]
.
Уже встречался с подобным. Геморрой неимоверный! Есть у меня пример, который работает именно так, но у меня "особые" условия!
Джо (2007-01-08 04:07:00) [10]> except
> Result:=false;
> end;
Не стоит так делать, ИМХО. Ты маскируешь ошибку, причем скрываешь ее причину, выдывая взамен малоинформативный False.
koha (2007-01-08 04:03:00) [11]Вот еще дописал к этому модулю одну функцию уже с учетом всех высказываний выше, которая извлекает в файл сжатый ресур по ResId.
Function DecompressResIdToFile(ResId: Integer; OutFileName: String): Boolean;
Var
Buffer: Array[0..1023] of char;
ByteRaed: Integer;
begin
Try
try
RES_STRM := TResourceStream.CreateFromID(HInstance,ResId,RT_RCDATA);
OUT_STRM := TFileStream.Create(OutFileName,fmCreate);
DECOMPRESS_STRM := TDecompressionStream.Create(OUT_STRM);
repeat
ByteRaed := INP_STRM.Read(Buffer,SizeOf(Buffer));
DECOMPRESS_STRM.Write(Buffer,ByteRaed);
until ByteRaed < 1024;
Result:=True;
except
Result:=false;
end;
finally
DECOMPRESS_STRM.Free;
RES_STRM.Free;
OUT_STRM.Free;
end;
end;
Германн (2007-01-08 03:48:00) [12]
> Anatoly Podgoretsky © (08.01.07 03:27) [11]
>
> > Германн (08.01.2007 03:24:10) [10]
>
> Конечно я бы не стал так писать, это же голову надо влево
> наклонять
> Более понятно и естественно писать так.
>
> try
> try
> except
> end
> finally
> end
>
Ну и я про тоже сказал в [3].
Anatoly Podgoretsky (2007-01-08 03:27:00) [13]> Германн (08.01.2007 03:24:10) [10]
Конечно я бы не стал так писать, это же голову надо влево наклонять
Более понятно и естественно писать так.
try
try
except
end
finally
end
Германн (2007-01-08 03:24:00) [14]
> Anatoly Podgoretsky © (08.01.07 02:51) [4]
>
> > Германн (08.01.2007 02:43:03) [3]
>
> В данном случае без разницы, сначала отработает except,
> потом finally
Но читается по разному, пока не поймёшь суть.
Anatoly Podgoretsky (2007-01-08 03:24:00) [15]> koha (08.01.2007 03:13:08) [8]
try finally выполнится всегда, как бы не прерывалось выполнение блока. Можно даже делать exit из процедуры в любом месте. except будет выполнен при исключение, затем будет выполнен finally для твоего кода.
koha (2007-01-08 03:13:00) [16]И в случае критической ошибки будет ли выполнено обязательно
try finally //..... end;
Anatoly Podgoretsky (2007-01-08 02:58:00) [17]> koha (08.01.2007 02:54:05) [5]
> - стоит ли делать это
Не стоит, после выхода из процедуры буфер прекращает свое существование
Джо (2007-01-08 02:57:00) [18]> [5] koha © (08.01.07 02:54)
> - стоит ли делать это
> for ByteRaed:=0 to 1023 do Buffer[ByteRaed]:=#0;
Нет, это совершенно бессмысленно.
koha (2007-01-08 02:54:00) [19]- стоит ли делать это
for ByteRaed:=0 to 1023 do Buffer[ByteRaed]:=#0;
нужно ли освобождать или уничтожать вуфер и как правильно делать?
- И вот еще ляпус сам исправил функции
CompressFile(InpFile: String; OutFile: String; N: Integer): boolean;
//..........
if N > 3 then N:=3; //N это степень сжатия
if N < 0 then N:=0;
COMPRESS_STRM := TCompressionStream.Create(TCompressionLevel(N),OUT_STRM);
//.............
Anatoly Podgoretsky (2007-01-08 02:51:00) [20]> Германн (08.01.2007 02:43:03) [3]
В данном случае без разницы, сначала отработает except, потом finally
Разница появляется когда после except должно продолжаться выполнение или блока или отдельных комманд, а вот дважды особождать не допустимо.