Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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.51 MB
Время: 0.043 c
15-1168014485
vidiv
2007-01-05 19:28
2007.01.28
Купил себе стиральную машину...


2-1168597598
newone
2007-01-12 13:26
2007.01.28
Работа с датами файлов


2-1168433997
NovaC
2007-01-10 15:59
2007.01.28
WinToDos &amp; CopyFile


15-1167686051
Riply
2007-01-02 00:14
2007.01.28
Книга по ассемблеру.


15-1168400743
Alex_ey
2007-01-10 06:45
2007.01.28
спящий режим





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский