Creating Compressed (Zipped) Folder using Delphi
Asked Answered
B

9

14

Can I create Windows XP's Compressed (Zipped) Folder using Delphi?

Buddleia answered 4/7, 2009 at 18:23 Comment(3)
What "zip property" are you referring to? Can you be a little more specific?Observance
Similar SO questions with relevant answers: How-do-i-compress-multiple-files-into-a-single-archive-with-delphi Using-7zip-from-delphiPredicable
Fast forward 2 years to 2011: Delphi XE2 now ships with a TZipFile class built into the RTL (see System.Zip). Maybe somebody who's actually used it could post an answer about it here.Coussoule
C
21

If you are using Delphi X2, just use TZipFile from System.Zip:

To Zip a folder, use:

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

To Zip files, use:

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

  Zip.Add('FileToBeZipped.txt');
  Zip.Add('ThisWillBeCompressedAgainForSureAndBecomeSmaller.zip');
finally
  Zip.Free;
end
Chiffon answered 20/1, 2012 at 19:5 Comment(4)
using this to zip a folder but keep getting " The process cannot access the file because its being useed by another process. not sure how its being accessed? I free the list i had with all the iamges in the folder. free the ini file i was writeing too. Any way to see What is accessing it? or any way to close what ever is accessing it..? thanksQuennie
@GlenMorse After 3 years I read this anser. The first function probably don't work. That generate the zip but only with the first file, maybe that function is blocking itself. Use the second aproach, it works fine.Shenitashenk
the first version works. You just need to get out of your own way. try something like TZipFile.ZipDirectoryContents('..\ZipFile.zip', 'C:\Zip\this\right\now');Chronogram
Using Delphi 10.3, compressing a folder, when I close my application, it hangs up. It wasn't hanging up before I added this. Note that I'm also doing it from within a thread. I do get a ZIP file in the end, and the code does pass successfully. Just, when I terminate the application, it gets stuck in the background...Damarisdamarra
L
5

According to a thread in eggheadcafe, you can use CreateFile Function with FILE_FLAG_BACKUP_SEMANTICS to create a Compressed Folder.

For shell extensions route, take a look at Using Windows XP "Compressed Folder" shell extension to work with .zip files by Namespace Edanmo, which is written in VB.

I just found the similar question asked on C++. Take a look at Creating a ZIP file on Windows (XP/2003) in C/C++. I have a feeling the easiest route is buying ZipForge. See Zip a file in Delphi code sample.

Leonelleonelle answered 4/7, 2009 at 18:43 Comment(0)
C
4

Some time ago, I've tried all of the Delphi compression libraries that I could find, and eventually I ended up using KaZip by Kiril Antonov.

My requirements were:

  • Free;
  • Open source;
  • Native Delphi code;
  • No external dependencies (dll, exe). My most important requirement;
  • Small memory footprint;
  • Easy to use;

I use it mainly to turn .kml files into .kmz, and it does that amazingly fast.

Here's an example of how I use it:

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;
Coussoule answered 5/7, 2009 at 7:17 Comment(2)
to what object does that final "Free" apply? My guess is KaZip, but I don't have the rep to edit.Predicable
Ah, yes KaZip should be freed there.. Fixed it.. I cleaned this code up in the text editor of this page to make it a bit easier to read.. I guess I should've checked if it still works :)Coussoule
P
4

Take a look at this OpenSource SynZip unit. It's even faster for decompression than the default unit shipped with Delphi, and it will generate a smaller exe (crc tables are created at startup).

No external dll is needed. Works from Delphi 6 up to XE. No problem with Unicode version of Delphi. All in a single unit.

I just made some changes to handle Unicode file names inside Zip content, not only Win-Ansi charset but any Unicode chars. Feedback is welcome.

Parcheesi answered 18/5, 2011 at 6:9 Comment(1)
can you give an example to use SynZip ? from example how to zip a folder?Sevenup
C
3

You could use TurboPower Abbrevia which is now open source.

Corron answered 4/7, 2009 at 20:4 Comment(0)
N
2

A "zipped" folder in Windows is nothing more than a .ZIP file compressed using any standard zip library. Compressed folders are a different animal and require an NTFS disk format.

For the "Zip" file, I strongly suggest the Turbo Power Abbrevia, which is open source and works well. You might want to check this alternate site if your using Delphi 2009 as it might be a more recent copy.

If your wanting to use the compressed folders option, you will need to modify the directory flags on the directory handle. This will only impact NEW files added to that directory and will not automatically compress existing files. If you have an existing directory you are trying to compress, then rename each existing file, and load and save it back to the original name deleting the original file when complete with each one. Yozey had a good link to the MSDN documentation. Just remember that this only works with NTFS formatted disks, so you will need to add a check for that in your code.

Nonresistant answered 6/7, 2009 at 16:34 Comment(0)
W
1

You can use some command line version of any compressor like 7zip and do the task using ShellExecute, or you can use a free or comercial component like anyone of these.

I had used ZipMaster and it behaves very well for my purpose. I don't know what are your size, space and performance requirements.

Wouldst answered 4/7, 2009 at 19:28 Comment(1)
I'm currently using it too, fits exactaly my needs.Cordiform
B
1

Take a look at these:

Bentlee answered 4/7, 2009 at 20:12 Comment(0)
D
0

The TZipFile.ZipDirectoryContents method did not work for me, so I created my own implementation using TZipFile.add(). I am posting it here if anyone needs it.

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;
Deed answered 8/8, 2020 at 11:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.