使用Delphi创建压缩(zipped)文件夹

14

我能用 Delphi 创建 Windows XP 的压缩文件夹吗?


1
你所指的“zip属性”是什么?你能再具体一些吗? - Mason Wheeler
3
快进2年到2011年:Delphi XE2现在已经内置了一个TZipFile类,作为RTL的一部分(请参阅System.Zip)。也许有人曾经使用过它,并可以在此发表回答。 - Wouter van Nifterick
9个回答

21
如果您使用的是Delphi X2,只需使用System.Zip中的TZipFile:
要压缩文件夹,请使用:
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

使用此方法压缩文件夹,但一直出现“由于另一个进程正在使用该文件,因此无法访问该文件”的错误。不确定是如何被访问的?我释放了包含文件夹中所有图像的列表。我也释放了正在写入的ini文件。有没有办法查看是什么在访问它?或者有没有办法关闭正在访问它的任何内容...?谢谢。 - Glen Morse
1
@GlenMorse 三年后我读到了这个答案。第一个函数可能不起作用。它只生成了第一个文件的压缩包,也许该函数正在阻塞自己。使用第二种方法,它可以正常工作。 - Edgar Muniz Berlinck
第一个版本可行。你只需要不要阻碍自己。 尝试像这样做: TZipFile.ZipDirectoryContents('..\ZipFile.zip', 'C:\Zip\this\right\now'); - Meta Mussel
使用Delphi 10.3压缩文件夹时,当我关闭应用程序时,它会挂起。在添加此功能之前,它并没有出现这种情况。请注意,我也是在线程内执行此操作。最终我确实得到了一个ZIP文件,并且代码也成功通过了。只是,当我终止应用程序时,它会在后台卡住... - Jerry Dodge

5

4

不久前,我尝试了所有能找到的Delphi压缩库,最终选择了KaZip,作者是Kiril Antonov

我的要求如下:

  • 免费;
  • 开源;
  • 本地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;

那个最后的“Free”应用于哪个对象?我猜是KaZip,但我没有编辑权限。 - Argalatyr
啊,是的,KaZip应该在那里被释放...已经修复了...我在这个页面的文本编辑器中清理了这段代码,使其更容易阅读...我想我应该检查一下它是否仍然有效 :) - Wouter van Nifterick

4
请看这个开源SynZip单元。它的解压速度比Delphi默认单元还要快,而且会生成更小的exe(crc表在启动时创建)。
不需要外部dll。适用于Delphi 6到XE。与Delphi的Unicode版本没有问题。所有内容都在一个单元中。
我只是做了一些更改,以处理Zip内容内部的Unicode文件名,不仅限于Win-Ansi字符集,而是任何Unicode字符。欢迎反馈。

2
你能给一个使用 SynZip 的例子吗?从这个例子中,如何压缩一个文件夹? - PresleyDias

3

2
在Windows中,“压缩文件夹”其实就是使用标准的ZIP库压缩的一个.ZIP文件。而“压缩文件夹”则是另一种不同的形式,需要NTFS磁盘格式。
对于“Zip”文件,我强烈建议使用开源且功能良好的Turbo Power Abbrevia。如果你使用Delphi 2009,可以查看这个备用站点,因为它可能是更新的副本。
如果你想使用压缩文件夹选项,你需要修改目录句柄上的目录标志。这只会影响添加到该目录的新文件,并不会自动压缩现有文件。如果你要压缩一个现有目录,则需要将每个现有文件重命名,并在完成后将其加载和保存回原始名称,删除原始文件。Yozey提供了一个MSDN文档的好链接。请记住,这仅适用于NTFS格式的磁盘,所以你需要在代码中添加一个检查。

1

你可以使用任何压缩程序的命令行版本,如7zip并使用ShellExecute完成任务,或者你可以使用免费或商用组件中的任何一个,例如这些

我曾使用ZipMaster,它非常适合我的用途。我不知道你的大小、空间和性能要求是什么。


我目前也在使用它,完全符合我的需求。 - Gedean Dias

1

0

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;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接