Создание сжатой (сжатой) папки с использованием 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;