【问题标题】:Creating Compressed (Zipped) Folder using Delphi使用 Delphi 创建压缩(Zipped)文件夹
【发布时间】:2009-07-04 18:23:59
【问题描述】:

我可以使用 Delphi 创建 Windows XP 的 Compressed (Zipped) 文件夹吗?

【问题讨论】:

标签: delphi winapi zip winzip compressed-folder


【解决方案1】:

如果您使用的是 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

【讨论】:

  • 使用它来压缩文件夹,但不断收到“该进程无法访问该文件,因为它被另一个进程使用。不确定它是如何被访问的?我释放了包含所有 iamges 的列表文件夹。释放我正在编写的 ini 文件。有什么方法可以查看正在访问它的内容吗?或者以任何方式关闭正在访问它的内容..?谢谢
  • @GlenMorse 3 年后,我读了这个分析器。第一个功能可能不起作用。这会生成 zip 但仅使用第一个文件,可能该功能正在阻止自己。使用第二种方法,效果很好。
  • 第一个版本有效。你只需要摆脱你自己的方式。尝试类似 TZipFile.ZipDirectoryContents('..\ZipFile.zip', 'C:\Zip\this\right\now');
  • 使用Delphi 10.3,压缩一个文件夹,当我关闭我的应用程序时,它挂断了。在我添加这个之前它没有挂断。请注意,我也是从一个线程中进行的。最后我确实得到了一个 ZIP 文件,并且代码确实通过了。只是,当我终止应用程序时,它会卡在后台......
【解决方案2】:

根据eggheadcafe中的一个帖子,您可以使用CreateFile FunctionFILE_FLAG_BACKUP_SEMANTICS创建一个压缩文件夹。

关于shell扩展路由,请看Using Windows XP "Compressed Folder" shell extension to work with .zip files的Namespace Edanmo,它是用VB编写的。

我刚刚发现在 C++ 上提出的类似问题。看看Creating a ZIP file on Windows (XP/2003) in C/C++。我觉得最简单的方法是购买 ZipForge。见Zip a file in Delphi code sample

【讨论】:

    【解决方案3】:

    前段时间,我尝试了所有能找到的 Delphi 压缩库,最终我最终使用了 KaZip by 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;
    

    【讨论】:

    • 最后的“免费”适用于什么对象?我猜是 KaZip,但我没有代表可以编辑。
    • 啊,是的,KaZip 应该在那里被释放.. 修复它.. 我在这个页面的文本编辑器中清理了这段代码,使它更容易阅读.. 我想我应该检查它是否仍然有效:)
    【解决方案4】:

    看看这个OpenSource SynZip unit。它的解压速度甚至比 Delphi 自带的默认单元更快,而且会生成更小的 exe(crc 表在启动时创建)。

    不需要外部 dll。适用于从 Delphi 6 到 XE。 Delphi 的 Unicode 版本没有问题。全部在一个单元中。

    我刚刚做了一些更改来处理 Zip 内容中的 Unicode 文件名,不仅是 Win-Ansi 字符集,还有任何 Unicode 字符。欢迎反馈。

    【讨论】:

    • 你能举个例子来使用SynZip吗?来自example 如何压缩文件夹?
    【解决方案5】:

    你可以使用TurboPower Abbrevia,它现在是开源的。

    【讨论】:

      【解决方案6】:

      Windows 中的“压缩”文件夹只不过是使用任何标准 zip 库压缩的 .ZIP 文件。压缩文件夹是另一种动物,需要 NTFS 磁盘格式。

      对于“Zip”文件,我强烈建议使用Turbo Power Abbrevia,它是开源的并且运行良好。如果您使用的是 Delphi 2009,您可能需要查看此 alternate 站点,因为它可能是更新的副本。

      如果您想使用压缩文件夹选项,您需要修改目录句柄上的目录标志。这只会影响添加到该目录的新文件,不会自动压缩现有文件。如果您有一个要压缩的现有目录,则重命名每个现有文件,然后将其加载并保存回原始名称,并在每个文件完成后删除原始文件。 Yozey 有一个很好的链接到MSDN 文档。请记住,这仅适用于 NTFS 格式的磁盘,因此您需要在代码中添加一个检查。

      【讨论】:

        【解决方案7】:

        您可以使用任何压缩器的某些命令行版本,例如 7zip,并使用 ShellExecute 执行任务,或者您可以使用免费或商业组件,例如 these 中的任何人。

        我使用过ZipMaster,它的表现非常适合我的目的。我不知道您对尺寸、空间和性能有什么要求。

        【讨论】:

        • 我现在也在用,正好符合我的需要。
        【解决方案8】:

        【讨论】:

          【解决方案9】:

          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;
          

          【讨论】:

            猜你喜欢
            • 2021-07-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-10-17
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多