Java 壓縮文件夾的代碼

jopen 11年前發布 | 29K 次閱讀 Java Java開發

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;

import org.apache.log4j.Logger; import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipFile; import org.apache.tools.zip.ZipOutputStream;

/**

  • 功能:zip壓縮、解壓(支持中文文件名)
  • 說明:使用Apache Ant提供的zip工具org.apache.tools.zip實現zip壓縮和解壓功能.
  • 解決了由于java.util.zip包不支持漢字的問題。
  • 使用java.util.zip包時,當zip文件中有名字為中文的文件時,
  • 就會出現異常:
  • "Exception in thread "main " java.lang.IllegalArgumentException
  • at java.util.zip.ZipInputStream.getUTF8String(ZipInputStream.java:285)
  • 注意:
  • 1、使用時把ant.jar放到classpath中,程序中使用 import org.apache.tools.zip.*;
  • 2、本程序使用Ant 1.7.1 中的ant.jar部分類,ant-zip-1.7.1只保留Ant的zip壓縮功能,以減小ant.jar的大小。
  • 4、ZipEntry的isDirectory()方法中,目錄以"/"結尾。

  • 可將主函數注釋去掉以單獨測試ZipFileUtils類。
  • Compile:
  • javac -cp Ant.jar ZipFileUtils.java
  • Usage:(將ant.jar直接放在當前目錄)
  • 壓縮: java -cp Ant.jar;. ZipFileUtils -zip [directoryName | fileName]...
  • 解壓: java -cp Ant.jar;. ZipFileUtils -unzip "fileName.zip"

*/ public class CompressBook { private static Logger log = Logger.getLogger(CompressBook.class);

private static int bufSize = 8096;    //size of bytes


/**
 * 壓縮文件夾內的所有文件和目錄(不支持有中文目錄或文件名)。
 *
 * @param zipDirectory 需要壓縮的文件夾名
 * @return 成功返回null,否則返回失敗信息
 */
public static String zip(String zipDirectory)
{
    File zipDir = new File(zipDirectory);
    return zip(zipDirectory, zipDir.getPath(), false);
}

/**
 * 壓縮文件夾內的所有文件和目錄(不支持有中文目錄或文件名)。
 *
 * @param zipDirectory   需要壓縮的文件夾名
 * @param zipFileName    壓縮后的zip文件名,如果后綴不是".zip, .jar, .war", 自動添加后綴".zip"。
 * @param includeSelfDir 是否包含自身文件夾
 * @return 成功返回null,否則返回失敗信息
 */
public static String zip(String zipDirectory, String zipFileName, boolean includeSelfDir)
{
    File zipDir = new File(zipDirectory);
    File[] willZipFileArr;
    if(includeSelfDir || zipDir.isFile())
    {
        willZipFileArr = new File[]{zipDir};
    }
    else
    {
        willZipFileArr = zipDir.listFiles();
    }
    return zip(willZipFileArr, zipFileName);
}

/**
 * 壓縮多個文件或目錄。可以指定多個單獨的文件或目錄。
 *
 * @param files       要壓縮的文件或目錄組成的File數組。
 * @param zipFileName 壓縮后的zip文件名,如果后綴不是".zip, .jar, .war",自動添加后綴".zip"。
 * @return 成功返回null,否則返回失敗信息
 */
public static String zip(File[] files, String zipFileName)
{
    if(files == null)
    {
        return "待壓縮的文件不存在。";
    }

    //未指定壓縮文件名,默認為"ZipFile"
    if(zipFileName == null || zipFileName.equals(""))
        zipFileName = "ZipFile";

    //添加".zip"后綴
    if(!zipFileName.toLowerCase().endsWith(".zip")
        && !zipFileName.toLowerCase().endsWith(".jar") && !zipFileName.toLowerCase().endsWith(".war"))
        zipFileName += ".zip";

    JarOutputStream jarOutput = null;
    try
    {
        jarOutput = new JarOutputStream(new FileOutputStream(zipFileName), new Manifest());

        for(File file : files)
        {
            zipFiles(file, jarOutput, "");
        }
        log.info("壓縮文件成功:" + zipFileName);

    } catch(Exception e)
    {
        log.error("異常", e);
    } finally
    {
        if(jarOutput != null)
        {
            try
            {
                jarOutput.close();
            } catch(IOException e)
            {
                log.error("jarOutput.close()異常", e);
            }
        }
    }
    return null;
}

/**
 * @param file     壓縮文件
 * @param jos      JarOutputStream
 * @param pathName 相對路徑
 * @throws Exception 異常
 */
private static void zipFiles(File file, JarOutputStream jos, String pathName)
    throws Exception
{
    String fileName = pathName + file.getName();
    if(file.isDirectory())
    {
        fileName = fileName + "/";
        jos.putNextEntry(new JarEntry(fileName));
        String fileNames[] = file.list();
        if(fileNames != null)
        {
            for(int i = 0; i < fileNames.length; i++)
            {
                zipFiles(new File(file, fileNames[i]), jos, fileName);
            }
            jos.closeEntry();
        }
    }
    else
    {
        JarEntry jarEntry = new JarEntry(fileName);
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
        jos.putNextEntry(jarEntry);

        byte[] buf = new byte[bufSize];
        int len;
        while((len = in.read(buf)) >= 0)
        {
            jos.write(buf, 0, len);
        }
        in.close();
        jos.closeEntry();
    }
}

/**
 * 壓縮文件夾內的所有文件和目錄。
 *
 * @param zipDirectory 需要壓縮的文件夾名
 * @return 成功返回null,否則返回失敗信息
 */
public static String antzip(String zipDirectory)
{
    File zipDir = new File(zipDirectory);
    return antzip(zipDirectory, zipDir.getPath(), false);
}

/**
 * 壓縮文件夾內的所有文件和目錄。
 *
 * @param zipDirectory   需要壓縮的文件夾名
 * @param zipFileName    壓縮后的zip文件名,如果后綴不是".zip, .jar, .war", 自動添加后綴".zip"。
 * @param includeSelfDir 是否包含自身文件夾
 * @return 成功返回null,否則返回失敗信息
 */
public static String antzip(String zipDirectory, String zipFileName, boolean includeSelfDir)
{
    File zipDir = new File(zipDirectory);
    File[] willZipFileArr;
    if(includeSelfDir || zipDir.isFile())
    {
        willZipFileArr = new File[]{zipDir};
    }
    else
    {
        willZipFileArr = zipDir.listFiles();
    }
    return antzip(willZipFileArr, zipFileName);
}

/**
 * 壓縮多個文件或目錄。可以指定多個單獨的文件或目錄。
 *
 * @param files       要壓縮的文件或目錄組成的File數組。
 * @param zipFileName 壓縮后的zip文件名,如果后綴不是".zip, .jar, .war",自動添加后綴".zip"。
 * @return 成功返回null,否則返回失敗信息
 */
public static String antzip(File[] files, String zipFileName)
{
    //未指定壓縮文件名,默認為"ZipFile"
    if(zipFileName == null || zipFileName.equals(""))
        zipFileName = "ZipFile";

    //添加".zip"后綴
    if(!zipFileName.toLowerCase().endsWith(".zip")
        && !zipFileName.toLowerCase().endsWith(".jar") && !zipFileName.toLowerCase().endsWith(".war"))
        zipFileName += ".zip";

    ZipOutputStream zipOutput = null;
    try
    {
        zipOutput = new ZipOutputStream(
            new BufferedOutputStream(new FileOutputStream(zipFileName)));
        zipOutput.setEncoding("GBK");

        for(File file : files)
        {
            antzipFiles(file, zipOutput, "");
        }

        log.info("壓縮文件成功:" + zipFileName);
    } catch(Exception e)
    {
        log.error("壓縮文件異常", e);
        return e.getMessage();
    }
    finally
    {
        try
        {
            assert zipOutput != null;
            zipOutput.close();
        } catch(Exception e)
        {
            log.error("異常", e);
        }
    }
    return null;
}

/**
 * @param file      壓縮文件
 * @param zipOutput ZipOutputStream
 * @param pathName  相對路徑
 * @throws Exception 異常
 */
private static void antzipFiles(File file, ZipOutputStream zipOutput, String pathName)
    throws Exception
{
    String fileName = pathName + file.getName();
    if(file.isDirectory())
    {
        fileName = fileName + "/";
        zipOutput.putNextEntry(new ZipEntry(fileName));
        String fileNames[] = file.list();
        if(fileNames != null)
        {
            for(int i = 0; i < fileNames.length; i++)
            {
                antzipFiles(new File(file, fileNames[i]), zipOutput, fileName);
            }
            zipOutput.closeEntry();
        }
    }
    else
    {
        ZipEntry jarEntry = new ZipEntry(fileName);
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
        zipOutput.putNextEntry(jarEntry);

        byte[] buf = new byte[bufSize];
        int len;
        while((len = in.read(buf)) >= 0)
        {
            zipOutput.write(buf, 0, len);
        }
        in.close();
        zipOutput.closeEntry();
    }
}

/**
 * 解壓指定zip文件。
 *
 * @param unZipFile 需要解壓的zip文件對象
 * @return 成功返回null,否則返回失敗信息
 */
public static String unZip(File unZipFile)
{
    return unZip(unZipFile.getPath(), null);
}

/**
 * 解壓指定zip文件到指定的目錄。
 *
 * @param unZipFile    需要解壓的zip文件對象
 * @param destFileName 解壓目的目錄
 * @return 成功返回null,否則返回失敗信息
 */
public static String unZip(File unZipFile, String destFileName)
{
    return unZip(unZipFile.getPath(), destFileName);
}

/**
 * 解壓指定zip文件。
 *
 * @param unZipFileName 需要解壓的zip文件名
 * @return 成功返回null,否則返回失敗信息
 */
public static String unZip(String unZipFileName)
{
    return unZip(unZipFileName, null);
}

/**
 * 解壓指定zip文件到指定的目錄。
 *
 * @param unZipFileName 需要解壓的zip文件名
 * @param destFileName  解壓目的目錄,如果為null則為當前zip文件所有目錄
 * @return 成功返回null,否則返回失敗信息
 */
public static String unZip(String unZipFileName, String destFileName)
{
    File unzipFile = new File(unZipFileName);

    if(destFileName == null || destFileName.trim().length() == 0)
    {
        destFileName = unzipFile.getParent();
    }

    File destFile;
    ZipFile zipFile = null;
    try
    {
        zipFile = new ZipFile(unzipFile, "GBK");
        for(Enumeration entries = zipFile.getEntries(); entries.hasMoreElements();)
        {
            ZipEntry entry = (ZipEntry) entries.nextElement();
            destFile = new File(destFileName, entry.getName());

            unZipFile(destFile, zipFile, entry); //執行解壓
        }
    } catch(Exception e)
    {
        log.error("解壓ZIP文件異常", e);
        return e.getMessage();
    }
    finally
    {
        try
        {
            assert zipFile != null;
            zipFile.close();
        } catch(Exception e)
        {
            log.error("異常", e);
        }
    }
    return null;
}

/* 執行解壓 */
private static void unZipFile(File destFile, ZipFile zipFile, ZipEntry entry)
    throws IOException
{
    InputStream inputStream;
    FileOutputStream fileOut;
    if(entry.isDirectory()) //是目錄,則創建之
    {
        destFile.mkdirs();
    }
    else //是文件
    {
        //如果指定文件的父目錄不存在,則創建之.
        File parent = destFile.getParentFile();
        if(parent != null && !parent.exists())
        {
            parent.mkdirs();
        }

        inputStream = zipFile.getInputStream(entry);

        fileOut = new FileOutputStream(destFile);
        byte[] buf = new byte[bufSize];
        int readedBytes;
        while((readedBytes = inputStream.read(buf)) > 0)
        {
            fileOut.write(buf, 0, readedBytes);
        }
        fileOut.close();

        inputStream.close();
    }
}

/**
 * 設置壓縮或解壓時緩沖區大小,單位字節。
 *
 * @param bufSize 緩沖區大小
 */
public void setBufSize(int bufSize)
{
    CompressBook.bufSize = bufSize;
}

//主函數,用于測試ZipFileUtils類
public static void main(String[] args) throws Exception
{
    //ZipFileUtils zip = new ZipFileUtils();

// if(args.length >= 2) // { // // if(args[0].equals("-zip")) // { // //將后續參數全部轉化為File對象 // File[] files = new File[args.length - 1]; // for(int i = 0; i < args.length - 1; i++) // { // files[i] = new File(args[i + 1]); // } // // //將第一個文件名作為zip文件名 // CompressBook.antzip(files, files[0].getName()); // return; // } // else if(args[0].equals("-unzip")) // { // CompressBook.unZip(args[1]); // return; // } // } // // String tmpFile = "D:/MyDocuments/Doc2009/2009-04/test/tagTable中文測試.zip"; // CompressBook.unZip(tmpFile); // CompressBook.unZip(tmpFile, tmpFile.substring(0, tmpFile.lastIndexOf("."))); // // String tmpDir = "D:\SVN\USCE.USEE\PCT\trunk\src\PCT_CJ001_Application\src\main\webapp\portals\king0.1\webapp"; // //ZipFileUtils.antzip(tmpDir, tmpDir + "/../war/pctant.war", false); // CompressBook.zip(tmpDir + "/test"); // //ZipFileUtils.zip(tmpDir, tmpDir + "/../war/pct.war", false); // // // ----------------- // System.out.println("Usage:"); // System.out.println("壓縮:java ZipFileUtils -zip [directoryName | fileName]... "); // System.out.println("解壓:java ZipFileUtils -unzip fileName.zip"); // System.out.println(); antzip("D:\apache-tomcat-6.0.30\webapps\hr\fileTemplate\tempFiles","c:\yasuo.rar",false); }

}</pre>

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!