Java ZIP File Example---refernce

时间:2014-04-13 13:07:32   收藏:0   阅读:826

In this tutorial we are going to see how to ZIP a file in Java. ZIP is an archive file format that enables data compression and it is mostly used on files and folders. A ZIP file may contain one or more compressed files or folders. Many compression algorithms have been used by several ZIP implementations, which are ubiquitous in many platforms. It is also possible to store a file in a ZIP archive file without compressing it.

Let’s start with a simple example of adding a single file to a ZIP archive.

1. Add a single file to a ZIP archive

In this example we are adding a regular file to a ZIP archive using java.util.zip utility classes.

ZipFileExample.java:

bubuko.com,布布扣
package com.javacodegeeks.core.zip;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipFileExample {

    private static final String INPUT_FILE = "C:\\Users\\nikos\\Desktop\\TestFiles\\testFile.txt";
    private static final String OUTPUT_FILE = "C:\\Users\\nikos\\Desktop\\TestFiles\\testFile.zip";

    public static void main(String[] args) {

        zipFile(new File(INPUT_FILE), OUTPUT_FILE);

    }

    public static void zipFile(File inputFile, String zipFilePath) {
        try {

            // Wrap a FileOutputStream around a ZipOutputStream
            // to store the zip stream to a file. Note that this is
            // not absolutely necessary
            FileOutputStream fileOutputStream = new FileOutputStream(zipFilePath);
            ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);

            // a ZipEntry represents a file entry in the zip archive
            // We name the ZipEntry after the original file‘s name
            ZipEntry zipEntry = new ZipEntry(inputFile.getName());
            zipOutputStream.putNextEntry(zipEntry);

            FileInputStream fileInputStream = new FileInputStream(inputFile);
            byte[] buf = new byte[1024];
            int bytesRead;

            // Read the input file by chucks of 1024 bytes
            // and write the read bytes to the zip stream
            while ((bytesRead = fileInputStream.read(buf)) > 0) {
                zipOutputStream.write(buf, 0, bytesRead);
            }

            // close ZipEntry to store the stream to the file
            zipOutputStream.closeEntry();

            zipOutputStream.close();
            fileOutputStream.close();

            System.out.println("Regular file :" + inputFile.getCanonicalPath()+" is zipped to archive :"+zipFilePath);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
bubuko.com,布布扣

The code is pretty self explanatory,but let’s go through each step:

Now if we run the above code this is the output:

Regular file :C:\Users\nikos\Desktop\TestFiles\testFile.txt is zipped to archive :C:\Users\nikos\Desktop\TestFiles\testFile.zip

Here is the folder before zipping this single file:

bubuko.com,布布扣

And this is after zipping “testFile.txt” :

bubuko.com,布布扣

2. Add a single folder to a ZIP archive

Now let’s see how you can add a simple folder, that contains only files to a zip archive.

ZipFileExample.java:

bubuko.com,布布扣
package com.javacodegeeks.core.zip;

import org.omg.CosNaming.NamingContextExtPackage.StringNameHelper;

import java.io.*;
import java.net.URI;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipFileExample {

    private static final String INPUT_FOLDER = "C:\\Users\\nikos\\Desktop\\TestFiles";
    private static final String ZIPPED_FOLDER = "C:\\Users\\nikos\\Desktop\\TestFiles.zip";

    public static void main(String[] args) {
        zipSimpleFolder(new File(INPUT_FOLDER),"", ZIPPED_FOLDER);
    }

    public static void zipSimpleFolder(File inputFolder, String parentName ,String zipFilePath ){

        try {
            FileOutputStream fileOutputStream = new FileOutputStream(zipFilePath);

            ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);

            String myname = parentName +inputFolder.getName()+"\\";

            ZipEntry folderZipEntry = new ZipEntry(myname);
            zipOutputStream.putNextEntry(folderZipEntry);

            File[] contents = inputFolder.listFiles();

            for (File f : contents){
                if (f.isFile())
                    zipFile(f,myname,zipOutputStream);
            }

            zipOutputStream.closeEntry();
            zipOutputStream.close();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void zipFile(File inputFile,String parentName,ZipOutputStream zipOutputStream) {

        try {
            // A ZipEntry represents a file entry in the zip archive
            // We name the ZipEntry after the original file‘s name
            ZipEntry zipEntry = new ZipEntry(parentName+inputFile.getName());
            zipOutputStream.putNextEntry(zipEntry);

            FileInputStream fileInputStream = new FileInputStream(inputFile);
            byte[] buf = new byte[1024];
            int bytesRead;

            // Read the input file by chucks of 1024 bytes
            // and write the read bytes to the zip stream
            while ((bytesRead = fileInputStream.read(buf)) > 0) {
                zipOutputStream.write(buf, 0, bytesRead);
            }

            // close ZipEntry to store the stream to the file

            zipOutputStream.closeEntry();

            System.out.println("Regular file :" + inputFile.getCanonicalPath()+" is zipped to archive :"+ZIPPED_FOLDER);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
bubuko.com,布布扣

The basic goal here is to zip a folder that contains only flat files. An important thing to notice here is that we create ZipEntry for the folder and add it to the archive. Then we create a Zip entry for each file in the folder. After zipping all the files in the folder and having created and closed all file zip entries we finally close the zip entry of the folder. Another important thing to notice is that we’ve added aparentName argument in the methods. That is basically to easily calculate the absolute path of each file in order to place it in the correct folder in the archive. Our situation here is very simple as we have only one parent folder in the archive.

Now if we run the above code this is the output:

Regular file :TestFiles\testFile.txt is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip

Here is the zipped folder :

bubuko.com,布布扣

And you can see that it contains a singe file:

bubuko.com,布布扣

3. Add a complete directory tree to a ZIP archive

In this section we are going to add a complete directory tree in the archive. This means that our parent directory might not only contain flat files, but a folder as well, which in turn might contain other files and folders etc.

Let’s see a recursive solution:

ZipFileExample.java:

bubuko.com,布布扣
package com.javacodegeeks.core.zip;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipFileExample {


    private static final String INPUT_FOLDER = "C:\\Users\\nikos\\Desktop\\TestFiles";
    private static final String ZIPPED_FOLDER = "C:\\Users\\nikos\\Desktop\\TestFiles.zip";

    public static void main(String[] args) {

        try {

            zip( INPUT_FOLDER, ZIPPED_FOLDER);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public static void zip(String inputFolder,String targetZippedFolder)  throws IOException {

        FileOutputStream fileOutputStream = null;

        fileOutputStream = new FileOutputStream(targetZippedFolder);
        ZipOutputStream zipOutputStream = new ZipOutputStream(fileOutputStream);

        File inputFile = new File(inputFolder);

        if (inputFile.isFile())
            zipFile(inputFile,"",zipOutputStream);
        else if (inputFile.isDirectory())
            zipFolder(zipOutputStream,inputFile,"");

        zipOutputStream.close();
    }

    public static void zipFolder(ZipOutputStream zipOutputStream,File inputFolder, String parentName)  throws IOException {

        String myname = parentName +inputFolder.getName()+"\\";

        ZipEntry folderZipEntry = new ZipEntry(myname);
        zipOutputStream.putNextEntry(folderZipEntry);

        File[] contents = inputFolder.listFiles();

        for (File f : contents){
            if (f.isFile())
                zipFile(f,myname,zipOutputStream);
            else if(f.isDirectory())
                zipFolder(zipOutputStream,f, myname);
        }
        zipOutputStream.closeEntry();
    }

    public static void zipFile(File inputFile,String parentName,ZipOutputStream zipOutputStream) throws IOException{

        // A ZipEntry represents a file entry in the zip archive
        // We name the ZipEntry after the original file‘s name
        ZipEntry zipEntry = new ZipEntry(parentName+inputFile.getName());
        zipOutputStream.putNextEntry(zipEntry);

        FileInputStream fileInputStream = new FileInputStream(inputFile);
        byte[] buf = new byte[1024];
        int bytesRead;

        // Read the input file by chucks of 1024 bytes
        // and write the read bytes to the zip stream
        while ((bytesRead = fileInputStream.read(buf)) > 0) {
            zipOutputStream.write(buf, 0, bytesRead);
        }

        // close ZipEntry to store the stream to the file
        zipOutputStream.closeEntry();

        System.out.println("Regular file :" + parentName+inputFile.getName() +" is zipped to archive :"+ZIPPED_FOLDER);
    }
}
bubuko.com,布布扣

As you can see inside zipFolder method we simply add a recursive call if the file we are trying to zip is a directory. That’s it. Notice that we create our ZipOutputStream to the top level zip method, so that all methods calls from then on can use the same instance of that stream. If we left the code as before, every time zipFolder was called, a new ZipOutputStream would be created, something that we definitely don’t want.

To test this, I’ve copied an Eclipse Project folder in my TestFiles folder.

Now if we run the above code this is the output:

Regular file :TestFiles\EJBInterceptor\EJBInterceptorEAR\.project is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
Regular file :TestFiles\EJBInterceptor\EJBInterceptorEAR\.settings\org.eclipse.wst.common.component is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
Regular file :TestFiles\EJBInterceptor\EJBInterceptorEAR\.settings\org.eclipse.wst.common.project.facet.core.xml is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
Regular file :TestFiles\EJBInterceptor\EJBInterceptorEAR\EarContent\META-INF\application.xml is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
Regular file :TestFiles\EJBInterceptor\InterceptorsEJB\.classpath is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
Regular file :TestFiles\EJBInterceptor\InterceptorsEJB\.project is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
Regular file :TestFiles\EJBInterceptor\InterceptorsEJB\.settings\org.eclipse.jdt.core.prefs is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
Regular file :TestFiles\EJBInterceptor\InterceptorsEJB\.settings\org.eclipse.wst.common.component is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
Regular file :TestFiles\EJBInterceptor\InterceptorsEJB\.settings\org.eclipse.wst.common.project.facet.core.xml is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
Regular file :TestFiles\EJBInterceptor\InterceptorsEJB\build\classes\com\javacodegeeks\enterprise\ejb\interceptor\SecondInterceptor.class is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
Regular file :TestFiles\EJBInterceptor\InterceptorsEJB\build\classes\com\javacodegeeks\enterprise\ejb\interceptor\SimpleInterceptor.class is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
Regular file :TestFiles\EJBInterceptor\InterceptorsEJB\build\classes\com\javacodegeeks\enterprise\ejb\SimpleEJB.class is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
Regular file :TestFiles\EJBInterceptor\InterceptorsEJB\build\classes\META-INF\ejb-jar.xml is zipped to archive :C:\Users\nikos\Desktop\TestFiles.zip
...

Now you can use this simple zip method as a utility to zip a normal file or a complete file path.

Here you can see the zipped folder:

bubuko.com,布布扣

And from there you can navigate the file path. For example :

bubuko.com,布布扣

4. Compressing files

java.util.zip basically offers two methods to compressed the files that you add in the archive: STORED and DEFLATED. In STORED method, you basically store the files uncompressed, it just stores the raw bytes. DEFLATED on the other hand uses the LZ77 alogrithm and Huffman code to perform compression on the files. You can specify which compression algorithm you want to use at each individualZipEntry using setMethod(ZipEntry.STORED) or setMethod(ZipEntry.DEFLATED) ZipEntry API methods.

Additionally you can specify other characteristics of the compressed components, to increase security and consistency of the contents of the archive. These include the size of the file and the check sum of the file. For the check sum java.util.zip offers a utility to calculate CRC32 checksum of the file. You can then add it to the ZipEntry using its setCrc API method. It is not always advisable to compress all the files in DEFLATED mode, because it simply takes more time.

Download Source Code

This was a Java ZIP File Example. You can download the source code of this example here : ZIPFileExample.zip

Java ZIP File Example---refernce,布布扣,bubuko.com

原文:http://www.cnblogs.com/davidwang456/p/3661973.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!