java zip 壓縮與解壓


java zip 壓縮與解壓


import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import org.apache.commons.lang3.StringUtils;

public class ZipUtil {

	/**
	 * 遞歸壓縮文件夾
	 * 
	 * @param srcRootDir
	 *            壓縮文件夾根目錄的子路徑
	 * @param file
	 *            當前遞歸壓縮的文件或目錄對象
	 * @param zos
	 *            壓縮文件存儲對象
	 * @throws Exception
	 */
	private static void zip(String srcRootDir, File file, ZipOutputStream zos) throws Exception {
		if (file == null) {
			return;
		}

		// 如果是文件,則直接壓縮該文件
		if (file.isFile()) {
			int count, bufferLen = 1024;
			byte data[] = new byte[bufferLen];

			// 獲取文件相對於壓縮文件夾根目錄的子路徑
			String subPath = file.getAbsolutePath();
			int index = subPath.indexOf(srcRootDir);
			if (index != -1) {
				subPath = subPath.substring(srcRootDir.length() + File.separator.length());
			}
			ZipEntry entry = new ZipEntry(subPath);
			zos.putNextEntry(entry);
			BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
			while ((count = bis.read(data, 0, bufferLen)) != -1) {
				zos.write(data, 0, count);
			}
			bis.close();
			zos.closeEntry();
		}
		// 如果是目錄,則壓縮整個目錄
		else {
			// 壓縮目錄中的文件或子目錄
			File[] childFileList = file.listFiles();
			for (int n = 0; n < childFileList.length; n++) {
				childFileList[n].getAbsolutePath().indexOf(file.getAbsolutePath());
				zip(srcRootDir, childFileList[n], zos);
			}
		}
	}

	/**
	 * 對文件或文件目錄進行壓縮
	 * 
	 * @param srcPath
	 *            要壓縮的源文件路徑。如果壓縮一個文件,則為該文件的全路徑;如果壓縮一個目錄,則為該目錄的頂層目錄路徑
	 * @param zipPath
	 *            壓縮文件保存的路徑。注意:zipPath不能是srcPath路徑下的子文件夾
	 * @param zipFileName
	 *            壓縮文件名
	 * @throws Exception
	 */
	public static void zip(String srcPath, String zipPath, String zipFileName) throws Exception {
		
		CheckedOutputStream cos = null;
		ZipOutputStream zos = null;
		try {
			File srcFile = new File(srcPath);

			// 判斷壓縮文件保存的路徑是否為源文件路徑的子文件夾,如果是,則拋出異常(防止無限遞歸壓縮的發生)
			if (srcFile.isDirectory() && zipPath.indexOf(srcPath) != -1) {
				throw new Exception("壓縮文件保存的路徑是否為源文件路徑的子文件夾");
			}

			// 判斷壓縮文件保存的路徑是否存在,如果不存在,則創建目錄
			File zipDir = new File(zipPath);
			if (!zipDir.exists() || !zipDir.isDirectory()) {
				zipDir.mkdirs();
			}

			// 創建壓縮文件保存的文件對象
			String zipFilePath = zipPath + File.separator + zipFileName;
			File zipFile = new File(zipFilePath);

			cos = new CheckedOutputStream(new FileOutputStream(zipFile), new CRC32());
			zos = new ZipOutputStream(cos);

			// 如果只是壓縮一個文件,則需要截取該文件的父目錄
			String srcRootDir = srcPath;
			if (srcFile.isFile()) {
				int index = srcPath.lastIndexOf(File.separator);
				if (index != -1) {
					srcRootDir = srcPath.substring(0, index);
				}
			}
			// 調用遞歸壓縮方法進行目錄或文件壓縮
			zip(srcRootDir, srcFile, zos);
			zos.flush();
		} catch (Exception e) {
			throw e;
		} finally {
			try {
				if (zos != null) {
					zos.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 解壓縮zip包
	 * 
	 * @param zipFilePath
	 *            zip文件的全路徑
	 * @param unzipFilePath
	 *            解壓后的文件保存的路徑
	 * @param includeZipFileName
	 *            解壓后的文件保存的路徑是否包含壓縮文件的文件名。true-包含;false-不包含
	 */
	@SuppressWarnings({ "unchecked", "resource" })
	public static void unzip(String zipFilePath, String unzipFilePath, boolean includeZipFileName) throws Exception {
		File zipFile = new File(zipFilePath);
		// 如果解壓后的文件保存路徑包含壓縮文件的文件名,則追加該文件名到解壓路徑
		if (includeZipFileName) {
			String fileName = zipFile.getName();
			if (StringUtils.isNotEmpty(fileName)) {
				fileName = fileName.substring(0, fileName.lastIndexOf("."));
			}
			unzipFilePath = unzipFilePath + File.separator + fileName;
		}
		// 創建解壓縮文件保存的路徑
		File unzipFileDir = new File(unzipFilePath);
		if (!unzipFileDir.exists() || !unzipFileDir.isDirectory()) {
			unzipFileDir.mkdirs();
		}

		// 開始解壓
		ZipEntry entry = null;
		String entryFilePath = null, entryDirPath = null;
		File entryFile = null, entryDir = null;
		int index = 0, count = 0, bufferSize = 1024;
		byte[] buffer = new byte[bufferSize];
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		ZipFile zip = new ZipFile(zipFile);
		Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>) zip.entries();
		// 循環對壓縮包里的每一個文件進行解壓
		while (entries.hasMoreElements()) {
			entry = entries.nextElement();
			// 構建壓縮包中一個文件解壓后保存的文件全路徑
			entryFilePath = unzipFilePath + File.separator + entry.getName();
			// 構建解壓后保存的文件夾路徑
			index = entryFilePath.lastIndexOf(File.separator);
			if (index != -1) {
				entryDirPath = entryFilePath.substring(0, index);
			} else {
				entryDirPath = "";
			}
			entryDir = new File(entryDirPath);
			// 如果文件夾路徑不存在,則創建文件夾
			if (!entryDir.exists() || !entryDir.isDirectory()) {
				entryDir.mkdirs();
			}

			// 創建解壓文件
			entryFile = new File(entryFilePath);

			// 寫入文件
			bos = new BufferedOutputStream(new FileOutputStream(entryFile));
			bis = new BufferedInputStream(zip.getInputStream(entry));
			while ((count = bis.read(buffer, 0, bufferSize)) != -1) {
				bos.write(buffer, 0, count);
			}
			bos.flush();
			bos.close();
		}
	}

	public static void main(String[] args) {
		String usersHome = System.getProperty("user.home");
		// 壓縮后文件存儲路徑
		String targetZipPath = usersHome + "/testzip";
		// 壓縮源文件(如果是文件, 則為全路徑 /groovy.png)
		String sourcePath = usersHome + "/Documents/bakpic/testzip";
		// 壓縮后文件名
		String zipFileName = "hehe.zip";
		try {
			zip(sourcePath, targetZipPath, zipFileName);
		} catch (Exception e) {
			e.printStackTrace();
		}

		// 解壓源文件路徑
		String zipFilePath = usersHome + "/testzip/hehe.zip";
		// 解壓后文件存儲路徑
		String unzipFilePath = usersHome + "/testzip/haha";
		try {
			unzip(zipFilePath, unzipFilePath, false);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM