Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Модуль Compress.pas - распаковка ресурсов в файл


Страницы:   1 2

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 должно продолжаться выполнение или блока или отдельных комманд, а вот дважды особождать не допустимо.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо