Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 620
  • Last Modified:

Create Zip file for Mac while preserving folder directory structure

In my application I am zipping up a directory structure on the server (Linux or PC) and providing a link for the user to download the zip file.  It is important that when the user extract the files the full tree is preserved.  I am using java.util.zip.ZipEntry & java.util.zip.ZipOutputStream to do this.  This works fine with WinZip on PC.   But on Macs (a sizeable chunk of the user), when StuffIt extract the file, the directory names get merged as part of the file name.  So I get only a single folder with lots of files with long names (e.g. "D:\xxx\yyy\dd\hello.txt").  When I use tar and gzip on unix to create the file this does not happen, folder structures are preserved.  But when I use java this happens.  How do I get around this?  I am new to creating zip files with java so please be detailed in your explaination.

I am also looking for ways to creat zip file with "relative" path rather than "absolute" but haven't figure that out yet.  My code is running under Tomcat 4.1.  Could this be my problem?

 Here's the main part of my code:

  public boolean executeZip() throws
      IOException {

    String inputFiles = "D:\\download\\InDir\\08_24_ID5551212";
    String outZipFileName = "TestZip.zip";
    String outputZipFilePath = "D:\\download\\OutDir" + "\\" + outZipFileName;
    System.out.println("Zipping files in " + inputFiles);

    try {
      System.out.println("Output file path:" + outputZipFilePath);
      //create a ZipOutputStream to zip the data to
      ZipOutputStream zos = new
          ZipOutputStream(new FileOutputStream(outputZipFilePath));
      zipDir(inputFiles, zos);
      //close the stream
      File file = new File(outputZipFilePath);

      // Get the number of bytes in the file
      outputZipFileSize = file.length() / 1024;

    catch (InterruptedException e) {
      return false;
    catch (Exception e) {
      //handle exception
      return false;

    return true;

  public void zipDir(String dir2zip, ZipOutputStream zos) throws Exception {

    //create a new File object based on the directory we have to zip File
    File zipDir = new File(dir2zip);
    //get a listing of the directory content
    String[] dirList = zipDir.list();
    byte[] readBuffer = new byte[2156];
    int bytesIn = 0;
    //loop through dirList, and zip the files
    for (int i = 0; i < dirList.length; i++) {
      File f = new File(zipDir, dirList[i]);
      if (f.isDirectory()) {
        //if the File object is a directory, call this
        //function again to add its content recursively
        String filePath = f.getPath();
        zipDir(filePath, zos);
        //loop again
      //if we reached here, the File object f was not a directory
      //create a FileInputStream on top of f
      FileInputStream fis = new FileInputStream(f);
      //create a new zip entry
      ZipEntry anEntry = new ZipEntry(f.getPath());
      //place the zip entry in the ZipOutputStream object
      //now write the content of the file to the ZipOutputStream
      while ( (bytesIn = fis.read(readBuffer)) != -1) {
        zos.write(readBuffer, 0, bytesIn);
      //close the Stream
  • 3
  • 2
2 Solutions
Tommy BraasCommented:
You can truncate the path part of the ZipEntry. I.e., the path the ZipEntry has is the path with which it is stored in the Zip file. Before creating the ZipEntry, substring the file system path to something appropriate for your application.

Tommy BraasCommented:
Also, it would be a good idea to change all back slashes to forward slashes. Forward slashes are handled correctly on all platforms.

Hi tangowayne,

As orangehead911 said :
>> Also, it would be a good idea to change all back slashes to forward slashes.
but the actual reason is zip files only supports '/' as file separator.

>> ZipEntry anEntry = new ZipEntry(f.getPath());
maybe you don't want the fullpath in the zip file, but a relative one :
String fpath=f.getPath();
if (fpath.startsWith(abs_base_dir)) fpath=fpath.substring(abs_base_dir.length());
ZipEntry anEntry = new ZipEntry(fpath);

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

tangowayneAuthor Commented:
Thanks Webstorm and orangehead911.  It makes sense to me now and it's working beautifully.

Tommy BraasCommented:

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now