Improve company productivity with a Business Account.Sign Up

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 621
  • 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 & 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 = "";
    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 = != -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);

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

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

Tommy BraasCommented:
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

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