Форум по программированию в Delphi

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Форум по программированию в Delphi » Система и Delphi » Программирование системы в Delphi


Программирование системы в Delphi

Сообщений 1 страница 13 из 13

1

Спасибо, что Вы выбрали наш форум. Я надеюсь, что именно здесь Вы найдете ответы на все свои вопросы.

С уважением Булай Никита.

0

2

Здрасте! Подскажите пож-ста, что делать в такой ситуации: есть папка с файлами, нужно, чтобы программа брала и сжимала всё, что есть в этой папке в один компактный инсталлер. Буду рад ответу с приведенным кодом программы.

0

3

При программировании может возникнуть потребность собрать все содержимое папки (включая ее подпапки) в один файл, из которого можно потом обратно восстановить всю структуру упакованной папки. Подобным методом пользуются архиваторы, когда пользователь сжимает не один файл, а целиком папку или несколько файлов. В рассматриваемом здесь варианте никакого сжатия не предполагается. Ниже приведен модуль, позволяющий упаковать папку в файл, не производя сжатия данных и восстановить содержимое папки по упакованному файлу:

Code (Pascal):
unit Folders;

////////////////////////////////////////////////////////////////////////////////
//                                                                                                        //
//    М О Д У Л Ь   П Р Е О Б Р А З О В А Н И Я   П А П К И   В   Ф А Й Л     //
//                                                                                                        //
//                           И   О Б Р А Т Н О                                                    //
//                                                                                                        //
//               А В Т О Р : А К А Т О В    А Л Е К С Е Й                                //
//                                                                                                        //
////////////////////////////////////////////////////////////////////////////////

interface

uses Windows, SysUtils, Forms;

function DirToFile (DirName, FileName: string): Integer;
function FileToDir (FileName, DirName: string): Integer;

implementation

(* uses UProgress; *)

const BufSize = $FFFF;

var Buf: array[0..BufSize] of Byte;

function DirWork (Dir, Path: string; H: Integer): Integer;
// Рекурсивная обработка дерева папок:
var FSR: TSearchRec;
    Size, FIn, Sz, Md, Pt: Integer;
    FName: string;
begin
  {$I-}
  if FindFirst (Concat (Dir, Path, '\*.*') , faAnyFile, FSR) = 0 then
  begin
    repeat
      if (FSR.Name <> '.') and (FSR.Name <> '..') then
      begin
        if Path <> '' then FName := Concat (Path, '\', FSR.Name)
                      else FName := FSR.Name;
(*        FProgress.CaptPanel.Caption := FName;  // FProgress  - это форма в Delphi
        FProgress.Gauge1.MinValue := 0;
        FProgress.Gauge1.Progress := 0; *)
        FileWrite (H, FSR.Attr, SizeOf (FSR.Attr));
        Size := Length (FName);
        FileWrite (H, Size, SizeOf (Size));
        FileWrite (H, FName[1], Size);
        if (FSR.Attr and faDirectory) <> 0 then
        begin {папка:}
          Result := DirWork (Dir, FName, H);
          if Result <> 0 then Exit;
        end else
        begin {файл:}
          FIn := FileOpen (Concat (Dir, FName), fmOpenRead or fmShareDenyWrite);
          Size := GetFileSize (FIn, nil);
(*          FProgress.Gauge1.MaxValue := Size; *)
          if SizeOf (Buf) > 0 then Md := (Size div SizeOf (Buf)) div 100
                              else Md := 16;
          if Md = 0 then Md := 1;
          if Md > 16 then Md := 16;
          Sz := 0;
          FileWrite (H, Size, SizeOf (Size));
          repeat
            Size := FileRead (FIn, Buf, SizeOf (Buf));
            if Size > 0 then FileWrite (H, Buf, Size);
            Inc (Sz, Size);
            if Pt mod Md = 0 then
            begin
(*              FProgress.Gauge1.Progress := Sz; *)
              Application.ProcessMessages;
            end; {if}
            Inc (Pt);
          until Size <= 0;
          Application.ProcessMessages;
          FileClose (FIn);
        end; {if}
      end; {if}
    until FindNext (FSR) <> 0;
    FindClose (FSR);
  end; {if}
  {$I+}
  Result := IOResult;
end; {func DirWork}

function DirToFile (DirName, FileName: string): Integer;
// Преобразовать папку в файл:
var H, Res: Integer;
    F: file of Byte;
begin
  try
(*    Application.CreateForm(TFProgress, FProgress);
    FProgress.Show; *)
    {$I-}
    AssignFile (F, FileName);
    Rewrite (F);
    CloseFile (F);
    H := FileOpen (FileName, fmOpenWrite);
    Result := DirWork (Concat (DirName, '\'), '', H);
    FileClose (H);
    {$I+}
    Res := IOResult;
    if Res <> 0 then Result := Res;
  except
    Result := 1;
  end; {try}
(*  FProgress.Free; *)
end; {func DirToFile}

function FileToDir (FileName, DirName: string): Integer;
// Преобразовать файл в папку:
var H, FOut, Size, Sz, Attr, Md, Pt, MaxSz: Integer;
    F: file of Byte;
    FName: string;
    P: PChar;
begin
  try
(*    Application.CreateForm(TFProgress, FProgress);
    FProgress.Show; *)
    {$I-}
    if not DirectoryExists (DirName) then MkDir (DirName);
    H := FileOpen (FileName, fmOpenRead or fmShareDenyWrite);
    repeat
      if FileRead (H, Attr, SizeOf (Attr)) <= 0 then Break;
      FileRead (H, Size, SizeOf (Size));
      GetMem (P, Size);
      FileRead (H, P^, Size);
      SetString (FName, P, Size);
      FreeMem (P);
(*      FProgress.CaptPanel.Caption := FName;
      FProgress.Gauge1.MinValue := 0;
      FProgress.Gauge1.Progress := 0; *)
      FName := Concat (DirName, '\', FName);
      if (Attr and faDirectory) <> 0 then
      begin {папка:}
        if not DirectoryExists (FName) then MkDir (FName);
      end else
      begin {файл:}
        FileRead (H, Size, SizeOf (Size));
        AssignFile (F, FName);
        Rewrite (F);
        CloseFile (F);
        FOut := FileOpen (FName, fmOpenWrite);
        if SizeOf (Buf) > 0 then Md := (Size div SizeOf (Buf)) div 100
                            else Md := 16;
        if Md = 0 then Md := 1;
        if Md > 16 then Md := 16;
(*        FProgress.Gauge1.MaxValue := Size; *)
        MaxSz := Size;
        Pt := 0;
        repeat
          if Size > SizeOf (Buf) then Sz := SizeOf (Buf)
                                 else Sz := Size;
          FileRead (H, Buf, Sz);
          FileWrite (FOut, Buf, Sz);
          Dec (Size, Sz);
          if Pt mod Md = 0 then
          begin
(*            FProgress.Gauge1.Progress := MaxSz - Size; *)
            Application.ProcessMessages;
          end; {if}
          Inc (Pt);
        until Size <= 0;
        Application.ProcessMessages;
        Fileclose (FOut);
      end; {if}
      FileSetAttr (FName, Attr);
    until False;
    FileClose (H);
    {$I+}
    Result := IOResult;
  except
    Result := 1;
  end; {try}
(*  FProgress.Free; *)
end; {func FileToFile}

end.

Модуль содержит две функции:
function DirToFile (DirName, FileName: string): Integer; - упаковывает указанную папку DirName в файл с именем FileName.
function FileToDir (FileName, DirName: string): Integer; - распаковывает упакованный файл с именем FileName в папку с именем DirName.
Функции возвращают целочисленный результат, показывающий код ошибки. Если он равен нулю - операция прошла успешно.

Если упаковываемые папки не очень большие (в пределах 10 Мегабайт), то время, затрачиваемое на выполнение этих функций незначительное. Однако процесс упаковывания больших папок может занять существенное время. Для этого желательно вывести некоторый прогрессбар на экран пользователя, что бы у него не сложилось впечатления, что программа зависла. Для этого нужно убрать все комментарии в модуле, заключенные в скобки: (* и *). Кроме этого нужно создать модуль UProgress с формой FProgress, на которой разместить компонент с именем Gauge1 типа TGauge (закладка Samples палитры компонентов). Этот визуальный компонент и будет служить прогрессбаром, показывающем процент завершенности операции.

Однако надо обратить внимание на то, что создать упакованный файл размером более 4 Гигабайт не удастся - это максимальный размер файла, с которым может работать описываемый модуль.

А сжать файл можно с помощью zLib или другого похожего компонента!

0

4

Спасибо! А как этим зЛиб'ом упаковать?

0

5

Надо подключить модуль zLib -

Uses ..., zlib, вроде так называется. А далее использовать приведенные в нем функции и процедуры.

0

6

Скачал с Вашего сайта Аманду Инсталлер. По какой-то причине пакует только папки, а файлы - нет.

0

7

Потому что использует выше приведенный код. Просто все файлы и папки копируются в папку Temp, а затем упаковываются в инсталлятор.

0

8

Я пробовал даже сразу закидывать всё в эту папку - всё равно пакует только папки. У меня было несколько папок общим объёмом 50 Мб, а после упаковки выходной файл стал 300 Кб. Так даже WinRar и 7-Zip не сжимают! Я распаковал, а оказалось, что все папки пусты, т.е. в директории установки папки есть, а файлов в них нет.

0

9

Возможно у тебя какая-нибудь ошибка в коде. Проверь все досканально. Советую каждое действие записывать в Memo или отдельный файл, чтоб понять, если где-то ошибочка.

0

10

Я это писал про аманду

0

11

А, не знаю, у меня все получается нормально. Возможно ты что-то не так делаешь. А вообще юзать Inno Setup.

0

12

инно платный - ну его

0

13

Согласен. Тему закрываем.

0


Вы здесь » Форум по программированию в Delphi » Система и Delphi » Программирование системы в Delphi