Форум: "Начинающим";
Текущий архив: 2007.01.28;
Скачать: [xml.tar.bz2];
ВнизМодуль Compress.pas - распаковка ресурсов в файл Найти похожие ветки
← →
koha © (2007-01-08 02:23) [0]Вот на скорую руку модуль состряпал для запаковки / файлов на основе 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.
← →
Anatoly Podgoretsky © (2007-01-08 02:28) [1]> koha (08.01.2007 02:23:00) [0]
Глубоко не смотрел, но один ляпсус налицо, при ошибке будет попытка повторного освобождения объектов и как результат AV
← →
Anatoly Podgoretsky © (2007-01-08 02:29) [2]> koha (08.01.2007 02:23:00) [0]
Убрать из except данные строки
DECOMPRESS_STRM.Free;
RES_STRM.Free;
OUT_STRM.Free;
for ByteRaed:=0 to 1023 do Buffer[ByteRaed]:=#0;
← →
Германн © (2007-01-08 02:43) [3]Я тоже взглянул только мельком. Но моё имхо - неверное вложение блоков. Блок except нужно вкладывать в блок finally. А не наоборот. Тогда и не будет желания делать то, что согласно [2] нужно убрать.
← →
Anatoly Podgoretsky © (2007-01-08 02:51) [4]> Германн (08.01.2007 02:43:03) [3]
В данном случае без разницы, сначала отработает except, потом finally
Разница появляется когда после except должно продолжаться выполнение или блока или отдельных комманд, а вот дважды особождать не допустимо.
← →
koha © (2007-01-08 02:54) [5]- стоит ли делать это
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);
//.............
← →
Джо © (2007-01-08 02:57) [6]> [5] koha © (08.01.07 02:54)
> - стоит ли делать это
> for ByteRaed:=0 to 1023 do Buffer[ByteRaed]:=#0;
Нет, это совершенно бессмысленно.
← →
Anatoly Podgoretsky © (2007-01-08 02:58) [7]> koha (08.01.2007 02:54:05) [5]
> - стоит ли делать это
Не стоит, после выхода из процедуры буфер прекращает свое существование
← →
koha © (2007-01-08 03:13) [8]И в случае критической ошибки будет ли выполнено обязательно
try finally //..... end;
← →
Anatoly Podgoretsky © (2007-01-08 03:24) [9]> koha (08.01.2007 03:13:08) [8]
try finally выполнится всегда, как бы не прерывалось выполнение блока. Можно даже делать exit из процедуры в любом месте. except будет выполнен при исключение, затем будет выполнен finally для твоего кода.
← →
Германн © (2007-01-08 03:24) [10]
> Anatoly Podgoretsky © (08.01.07 02:51) [4]
>
> > Германн (08.01.2007 02:43:03) [3]
>
> В данном случае без разницы, сначала отработает except,
> потом finally
Но читается по разному, пока не поймёшь суть.
← →
Anatoly Podgoretsky © (2007-01-08 03:27) [11]> Германн (08.01.2007 03:24:10) [10]
Конечно я бы не стал так писать, это же голову надо влево наклонять
Более понятно и естественно писать так.
try
try
except
end
finally
end
← →
Германн © (2007-01-08 03:48) [12]
> Anatoly Podgoretsky © (08.01.07 03:27) [11]
>
> > Германн (08.01.2007 03:24:10) [10]
>
> Конечно я бы не стал так писать, это же голову надо влево
> наклонять
> Более понятно и естественно писать так.
>
> try
> try
> except
> end
> finally
> end
>
Ну и я про тоже сказал в [3].
← →
koha © (2007-01-08 04:03) [13]Вот еще дописал к этому модулю одну функцию уже с учетом всех высказываний выше, которая извлекает в файл сжатый ресур по 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 04:07) [14]> except
> Result:=false;
> end;
Не стоит так делать, ИМХО. Ты маскируешь ошибку, причем скрываешь ее причину, выдывая взамен малоинформативный False.
← →
Германн © (2007-01-08 04:21) [15]Добавлю к
> Джо © (08.01.07 04:07) [14]
.
Уже встречался с подобным. Геморрой неимоверный! Есть у меня пример, который работает именно так, но у меня "особые" условия!
← →
koha © (2007-01-08 04:41) [16]> Джо © (08.01.07 04:07) [14]
> Германн © (08.01.07 04:21) [15]
- Тогда закономерный вопрос : как проконтролировать выполнение и не выполение функции?
← →
Джо © (2007-01-08 04:56) [17]> [16] koha © (08.01.07 04:41)
> > Джо © (08.01.07 04:07) [14]
> > Германн © (08.01.07 04:21) [15]
>
> - Тогда закономерный вопрос : как проконтролировать выполнение
> и не выполение функции?
Если не произошло исключения, значит процедура выполнилась успешно.
← →
koha © (2007-01-08 06:35) [18]> Если не произошло исключения, значит процедура выполнилась успешно
- вот именно этой процедуре, извеняюсь, т.е. функции можетбыть и вовсе нестоит быть функцией?
← →
Джо © (2007-01-08 06:39) [19]> [18] koha © (08.01.07 06:35)
> > Если не произошло исключения, значит процедура выполнилась
> успешно
>
> - вот именно этой процедуре, извеняюсь, т.е. функции можетбыть
> и вовсе нестоит быть функцией?
Может, и не стоит. По крайней мере, в таком варианте, когда на любую ошибку возвращается просто False, а не причина ошибки. Особого смысла в этом нет.
← →
app © (2007-01-08 07:07) [20]
> Тогда закономерный вопрос : как проконтролировать выполнение
> и не выполение функции?
Убери совсем except и далее смотри [17] и далее.
← →
koha © (2007-01-08 07:19) [21]> app © (08.01.07 07:07) [20]
> Убери совсем except и далее смотри [17] и далее.
- в таком случае предлагается наверное это:
try
Myfunction();
except //....... end;
← →
Anatoly Podgoretsky © (2007-01-08 07:29) [22]> koha (08.01.2007 07:19:21) [21]
Именно это тебе и предлагали, это более гибко.
← →
koha © (2007-01-08 07:56) [23]- в этом немного разобрался ведь по сути теперь особой разницы не видать как обработку ошибок вести или внутри функции или снаружи, я думаю это наверное зависить будет от того в каком месте программы функцию использовать. Меня так устраивает и такой вариант:
function();
try
//..........
result:=true;
except MessageDlg(); end;
//........
end;
Вот еще осталось написать пару функций, довольно актуальных, которые при помощи Zlib сжимали и расжимали данные перед и после отправки пакетов по сети.
Дописать утилиту, которая будет готовить из файлов сжатые ресурсы и выложить на свой сайт и будет все шоколаде шоколаде.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.01.28;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.077 c