Создание сжатой (сжатой) папки с использованием Delphi

Могу ли я создать сжатую (сжатую) папку Windows XP с помощью Delphi?

8 ответов

Если вы используете Delphi X2, просто используйте TZipFile из System.Zip:

Чтобы сжать папку, используйте:

TZipFile.ZipDirectoryContents('ZipFile.zip', 'C:\Zip\this\right\now');

Чтобы заархивировать файлы, используйте:

Zip := TZipFile.Create;
try
  Zip.Open('ZipFile.zip', zmWrite);

  Zip.Add('FileToBeZipped.txt');
  Zip.Add('ThisWillBeCompressedAgainForSureAndBecomeSmaller.zip');
finally
  Zip.Free;
end

Согласно потоку в eggheadcafe, вы можете использовать функцию CreateFile с FILE_FLAG_BACKUP_SEMANTICS создать сжатую папку.

Что касается маршрутизации расширений оболочки, взгляните на Использование расширения оболочки Windows XP "Compressed Folder" для работы с файлами.zip от Namespace Edanmo, написанного на VB.

Я только что нашел аналогичный вопрос, заданный на C++. Посмотрите на Создание ZIP-файла в Windows (XP/2003) в C / C++. У меня ощущение, что самый простой маршрут - это покупка ZipForge. Смотрите Zip файл в примере кода Delphi.

Взгляните на этот блок OpenSource SynZip. Это даже быстрее для распаковки, чем модуль по умолчанию, поставляемый с Delphi, и он создаст меньший exe (таблицы crc создаются при запуске).

Никаких внешних DLL не требуется. Работает от Delphi 6 до XE. Нет проблем с Unicode-версией Delphi. Все в одном блоке.

Я только что сделал некоторые изменения для обработки имен файлов Unicode внутри содержимого Zip, не только для кодировки Win-Ansi, но и для любых символов Unicode. Обратная связь приветствуется.

Некоторое время назад я перепробовал все библиотеки сжатия Delphi, которые смог найти, и в итоге я использовал KaZip от Кирилла Антонова.

Мои требования были:

  • Свободно;
  • Открытый исходный код;
  • Родной код Delphi;
  • Нет внешних зависимостей (dll, exe). Мое самое важное требование;
  • Небольшой объем памяти;
  • Легко использовать;

Я использую его в основном для преобразования файлов.kml в.kmz, и это происходит на удивление быстро.

Вот пример того, как я его использую:

uses
  KaZip;

...

// replaces a .kml file with a .kmz file
procedure KmlToKmz(const aFileName: string);
var
  FS: TFileStream;
  KaZip:TKaZip;
  KmzFileName:TFileName;
begin
  KmzFileName := ChangeFileExt(aFileName, '.kmz');
  KaZip := TKaZip.Create(nil);
  try
    // create an empty zipfile with .kmz extension:
    FS := TFileStream.Create(KmzFileName, fmOpenReadWrite or FmCreate);
    try
      KaZip.CreateZip(FS);
    finally
      FS.Free;
    end;        

    KaZip.Open(KmzFileName); // Open the new .kmz zipfile
    KaZip.Entries.AddFile(aFileName); // add the .kml
    KaZip.Close; 
    DeleteFile(aFileName); // delete the .kml
  finally
    KaZip.Free;
  end;
end;

Вы можете использовать TurboPower Abbrevia с открытым исходным кодом.

Папка "zip" в Windows - это не что иное, как файл.ZIP, сжатый с помощью любой стандартной библиотеки zip. Сжатые папки являются другим животным и требуют формат диска NTFS.

Для файла "Zip" я настоятельно рекомендую использовать Turbo Power Abbrevia с открытым исходным кодом, который хорошо работает. Возможно, вы захотите проверить этот альтернативный сайт, если вы используете Delphi 2009, поскольку это может быть более свежая копия.

Если вы хотите использовать параметр сжатых папок, вам нужно будет изменить флаги каталога на дескрипторе каталога. Это повлияет только на новые файлы, добавленные в этот каталог, и не будет автоматически сжимать существующие файлы. Если у вас есть существующий каталог, который вы пытаетесь сжать, переименуйте каждый существующий файл, загрузите и сохраните его обратно к исходному имени, удалив исходный файл, когда он будет завершен с каждым. У Йози была хорошая ссылка на документацию MSDN. Просто помните, что это работает только с дисками, отформатированными в NTFS, поэтому вам нужно добавить проверку для этого в вашем коде.

Взгляните на это:

Вы можете использовать какую-либо версию командной строки любого компрессора, например 7zip, и выполнять задачу с помощью ShellExecute, или вы можете использовать бесплатный или коммерческий компонент, как любой из них.

Я использовал ZipMaster, и он ведет себя очень хорошо для моих целей. Я не знаю, каковы ваши требования к размеру, пространству и производительности.

Метод TZipFile.ZipDirectoryContents у меня не работал, поэтому я создал свою собственную реализацию с помощью TZipFile.add(). Выкладываю сюда, если кому-то понадобится.

procedure CreateZipOfDirectory(directory: string);
var
  zip: TZipFile;
  Arr: tarray<string>;
  str: string;
  
  function GetAllFilesInDir(const Dir: string): tarray<string>;
  var
    Search: TSearchRec;
    procedure addAll(arr: tarray<string>; parent: string);
    var
      tmp: string;
    begin
      for tmp in arr do
      begin
        setlength(result, length(result) + 1);
        result[length(result) - 1] := IncludeTrailingBackslash(parent) + tmp;
      end;
    end;
  begin
    setlength(result, 0);
    if FindFirst(IncludeTrailingBackslash(Dir) + '*.*', faAnyFile or faDirectory, Search) = 0 then
      try
        repeat
          if (Search.Attr and faDirectory) = 0 then
          begin
            setlength(result, length(result) + 1);
            result[length(result) - 1] := Search.Name;
          end
          else if (Search.Name <> '..') and (Search.Name <> '.') then
            addAll(GetAllFilesInDir(IncludeTrailingBackslash(Dir) + Search.Name), Search.Name);
        until FindNext(Search) <> 0;
      finally
        FindClose(Search);
      end;
  end;

begin
  Zip := TZipFile.Create;
  try
    Zip.Open('Foo.zip', zmWrite);
    arr := GetAllFilesInDir(directory); // The Delphi TZipFile.ZipDirectoryContents does not work properly, so let's create our own.
    for str in arr do
      zip.Add(directory + str, str); // Add the second parameter to make sure that the file structure is preserved.
  finally
    zip.Free;
  end;
end;
Другие вопросы по тегам