Java 文件壓縮與解壓

 

package com.archser.archser.util;

import java.io.*;

import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * 
 * @author 軒
 *
 */
public class ZipUtils {

	/** 緩衝器大小 */
	private static final int BUFFER = 1024;

	/**
	 * 取的給定源目錄下的所有文件及空的子目錄 遞歸實現
	 *
	 * @param srcFile
	 *
	 * @return
	 */
	private static List<File> getAllFiles(File srcFile) {
		List<File> fileList = new ArrayList<File>();
		File[] tmp = srcFile.listFiles();
		for (int i = 0; i < tmp.length; i++) {
			if (tmp[i].isFile()) {
				fileList.add(tmp[i]);
			}
			if (tmp[i].isDirectory()) {
				if (tmp[i].listFiles().length != 0) {// 若不是空目錄,則遞歸添加其下的目錄和文件
					fileList.addAll(getAllFiles(tmp[i]));
				} else {// 若是空目錄,則添加這個目錄到fileList
					fileList.add(tmp[i]);
				}
			}
		}  
		return fileList;
	}

	/**
	 * 取相對路徑 依據文件名和壓縮源路徑得到文件在壓縮源路徑下的相對路徑
	 *
	 * @param dirPath 壓縮源路徑
	 * @param file
	 *
	 * @return 相對路徑
	 */
	private static String getRelativePath(String dirPath, File file) {
		File dir = new File(dirPath);
		String relativePath = file.getName();
		while (true) {
			file = file.getParentFile();
			if (file == null) {
				break;
			}
			if (file.equals(dir)) {
				break;
			} else {
				relativePath = file.getName() + "/" + relativePath;
			}
		}  
		return relativePath;
	}

	/**
	 * 創建文件 根據壓縮包內文件名和解壓縮目的路徑,創建解壓縮目標文件, 生成中間目錄
	 * 
	 * @param dstPath  解壓縮目的路徑
	 * @param fileName 壓縮包內文件名
	 *
	 * @return 解壓縮目標文件
	 *
	 * @throws IOException
	 */
	private static File createFile(String dstPath, String fileName) throws IOException {
		String[] dirs = fileName.split("/");// 將文件名的各級目錄分解
		File file = new File(dstPath);

		if (dirs.length > 1) {// 文件有上級目錄
			for (int i = 0; i < dirs.length - 1; i++) {
				file = new File(file, dirs[i]);// 依次創建文件對象知道文件的上一級目錄
			}
			if (!file.exists()) {
				file.mkdirs();// 文件對應目錄若不存在,則創建
			}
			file = new File(file, dirs[dirs.length - 1]);// 創建文件
			return file;
		} else {
			if (!file.exists()) {
				file.mkdirs();// 若目標路徑的目錄不存在,則創建
			}
			file = new File(file, dirs[0]);// 創建文件
			return file;
		}
	}

	/**
	 * 解壓縮方法
	 *
	 *
	 * @param zipFileName 壓縮文件名
	 * @param dstPath     解壓目標路徑
	 *
	 * @return
	 */
	@SuppressWarnings("resource")
	public static boolean unzip(String zipFileName, String dstPath) {
		try {
			ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFileName));
			ZipEntry zipEntry = null;
			byte[] buffer = new byte[BUFFER];// 緩衝器
			int readLength = 0;// 每次讀出來的長度
			while ((zipEntry = zipInputStream.getNextEntry()) != null) {
				if (zipEntry.isDirectory()) {// 若是zip條目目錄,則需創建這個目錄
					File dir = new File(dstPath + "/" + zipEntry.getName());
					if (!dir.exists()) {
						dir.mkdirs();
						continue;// 跳出
					}
				}
				File file = createFile(dstPath, zipEntry.getName());// 若是文件,則需創建該文件
				OutputStream outputStream = new FileOutputStream(file);
				while ((readLength = zipInputStream.read(buffer, 0, BUFFER)) != -1) {
					outputStream.write(buffer, 0, readLength);
				}
				outputStream.close();
			} // end while
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	public static void main(String[] args) {
		zip("F:\\zip","F:\\3.zip"); //壓縮文件或文件夾
	}

	/**
	 * 壓縮方法 (可以壓縮空的子目錄)
	 * 
	 * @param srcPath     壓縮源路徑
	 * @param zipFileName 目標壓縮文件
	 *
	 * @return
	 */
	public static boolean zip(String srcPath, String zipFileName) {
		File srcFile = new File(srcPath);
		List<File> fileList = getAllFiles(srcFile);// 所有要壓縮的文件
		byte[] buffer = new byte[BUFFER];// 緩衝器
		ZipEntry zipEntry = null;
		int readLength = 0;// 每次讀出來的長度
		try {
			ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
			for (File file : fileList) {
				if (file.isFile()) {// 若是文件,則壓縮這個文件
					zipEntry = new ZipEntry(getRelativePath(srcPath, file));
					zipEntry.setSize(file.length());
					zipEntry.setTime(file.lastModified());
					zipOutputStream.putNextEntry(zipEntry);
					InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
					while ((readLength = inputStream.read(buffer, 0, BUFFER)) != -1) {
						zipOutputStream.write(buffer, 0, readLength);
					}
					inputStream.close();
				} else {// 若是目錄(即空目錄)則將這個目錄寫入zip條目
					zipEntry = new ZipEntry(getRelativePath(srcPath, file) + "/");
					zipOutputStream.putNextEntry(new ZipEntry(zipEntry+"/"));
				}
			} 
			zipOutputStream.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章