Java ZIP格式压缩、解压缩文件

概要:

Java.util.zip包实现了Zip格式相关的类库,使用格式zip格式压缩和解压缩时需要导入该包。

使用ZipOutputStream可以实现文件压缩,所有写入到ZipOutputStream输入流中的数据都会被Zip格式压缩。

每个被压缩的文件或目录在zip文件中都对应一个ZipEntry对象,每个ZipEntry都有一个name属性,表示它相对于zip文件目录的相对路径。对于目录,路径以“/”结尾;对于文件,路径以文件名结尾。

ZipOutputStream的putNextEntry()方法往zip文件中添加ZipEntry对象,紧接着写入到该文件ZipOutputStream流中的数据都被保存到ZipEntry中,调用ZipOutputStream的closeEntry()方法。

| |目录

package net.xsoftlab.baike;

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.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

public class TestReadZiP {
	// 压缩文件或者目录
	public static void zipFile(String baseDirName, String fileName, String toFileName) {
		if (baseDirName == null) { // 检测根目录是否存在
			System.out.println("压缩失败,根目录不存在:" + baseDirName);
			return;
		}
		File baseDir = new File(baseDirName); // 创建文件
		if (!baseDir.exists() || (!baseDir.isDirectory())) { // 判断文件是否是目录
			System.out.println("压缩失败,根目录不存在:" + baseDirName);
			return;
		}
		String baseDirPath = baseDir.getAbsolutePath();// 获得目录绝对路径
		File targetFile = new File(toFileName); // 目标文件
		try {
			ZipOutputStream out = new ZipOutputStream(new FileOutputStream(targetFile)); // 创建一个zip输出流来压缩数据并写入到zip文件
			if (fileName.equals("*")) { // 如果是*号则将指定目录下的所有文件压缩到ZIP
				TestReadZiP.dirToZip(baseDirPath, baseDir, out);// 调用方法进行压缩
			} else {// 压缩指定文件
				File file = new File(baseDir, fileName); // 创建文件
				if (file.isFile()) { // 压缩的是否是文件
					// 压缩文件到ZIP输出流
					TestReadZiP.fileToZip(baseDirPath, file, out);
				} else { // 压缩目录到ZIP输出流
					TestReadZiP.dirToZip(baseDirPath, file, out);
				}
			}
			out.close(); // ZIP输出流关闭
			System.out.println("压缩文件成功,目标文件名:" + toFileName);
		} catch (IOException e) { // 捕获异常
			System.out.println("压缩失败:" + e);
			e.printStackTrace();
		}
	}

	// 解压缩ZIP文件,zipFileName:待解压缩的ZIP文件名
	public static void upzipFile(String zipFileName, String targetBaseDirName) {
		if (!targetBaseDirName.endsWith(File.separator)) {
			targetBaseDirName += File.separator;
		}
		try {
			ZipFile zipFile = new ZipFile(zipFileName);// 根据ZIP文件创建ZipFile对象
			ZipEntry entry = null; // ZIP实体
			String entryName = null; // ZIP实体名
			String targetFileName = null;
			byte[] buffer = new byte[4096]; // 创建复制缓冲区
			int bytes_read;
			Enumeration entrys = zipFile.entries(); // 获取ZIP文件里所有的entry
			while (entrys.hasMoreElements()) { // 遍历所有entry
				entry = (ZipEntry) entrys.nextElement();// 依次获得所有entry
				entryName = entry.getName(); // 获得entry的名字
				targetFileName = targetBaseDirName + entryName;
				if (entry.isDirectory()) { // 判断是否是目录,如果是
					new File(targetFileName).mkdirs();// 创建目录
					continue;
				} else { // 如果是一个文件,则创建父目录
					new File(targetFileName).getParentFile().mkdirs();
				}
				// 创建文件
				File targetFile = new File(targetFileName);
				// 输出绝对路径
				System.out.println("创建文件:" + targetFile.getAbsolutePath());
				// 打开文件输出流
				FileOutputStream os = new FileOutputStream(targetFile);
				// 从ZipFile对象中打开entry的输入流
				InputStream is = zipFile.getInputStream(entry);
				// 循环将内容写入文件输出流
				while ((bytes_read = is.read(buffer)) != -1) {
					os.write(buffer, 0, bytes_read);
				}
				os.close(); // 关闭流
				is.close();
			}
			System.out.println("解压缩文件成功!");
		} catch (IOException err) {
			System.err.println("解压缩文件失败: " + err);
		}
	}

	private static void dirToZip(String baseDirPath, File dir, ZipOutputStream out) { // 将目录压缩到ZIP输出流
		if (dir.isDirectory()) { // 判断是否是目录
			File[] files = dir.listFiles(); // 将目录下的所有文件放在文件集中
			if (files.length == 0) { // 判断文件集是否为空
				ZipEntry entry = new ZipEntry(getEntryName(baseDirPath, dir));
				try {
					out.putNextEntry(entry); // 复制字节到压缩文件
					out.closeEntry(); // 关系流实体
				} catch (IOException e) {
					e.printStackTrace();
				}
				return;
			}
			for (int i = 0; i < files.length; i++) {
				if (files[i].isFile()) { // 如果是文件,调用fileToZip方法
					TestReadZiP.fileToZip(baseDirPath, files[i], out);
				} else { // 如果是目录,递归调用
					TestReadZiP.dirToZip(baseDirPath, files[i], out);
				}
			}
		}
	}

	private static void fileToZip(String baseDirPath, File file, ZipOutputStream out) { // 将文件压缩到ZIP输出流
		FileInputStream in = null;
		ZipEntry entry = null;
		byte[] buffer = new byte[4096]; // 创建复制缓冲区
		int bytes_read;
		if (file.isFile()) { // 如果是文件
			try {
				in = new FileInputStream(file); // 创建一个文件输入流
				// 创建ZIP实体
				entry = new ZipEntry(getEntryName(baseDirPath, file));
				out.putNextEntry(entry); // 存储项信息到压缩文件
				// 复制字节到压缩文件
				while ((bytes_read = in.read(buffer)) != -1) {
					out.write(buffer, 0, bytes_read);
				}
				out.closeEntry(); // 关系流实体
				in.close();
				System.out.println("添加文件" + file.getAbsolutePath() + "被到ZIP文件中!");
			} catch (IOException e) { // 捕获异常
				e.printStackTrace();
			}
		}
	}

	private static String getEntryName(String baseDirPath, File file) {
		// 获取待压缩文件相对于根目录的相对路径名
		if (!baseDirPath.endsWith(File.separator)) {
			baseDirPath += File.separator;
		}
		String filePath = file.getAbsolutePath(); // 获得绝对路径
		if (file.isDirectory()) { // 判断是否是目录
			filePath += "/"; // 是则加文件分隔符将以目录项存储
		}
		int index = filePath.indexOf(baseDirPath); // 获得根目录
		// 返回待压缩文件相对根目录的路径
		return filePath.substring(index + baseDirPath.length());
	}

	public static void main(String[] args) { // java程序主入口处
		// 压缩D盘下的createFile目录,压缩后的文件是D:/createFilel.zip
		String baseDirName = "D:/"; // 根目录
		String fileName = "createFile/"; // 文件名
		String zipFileName = "D:/createFile.zip"; // 目录文件名
		// 调用方法压缩文件或目录
		TestReadZiP.zipFile(baseDirName, fileName, zipFileName);
		System.out.println(); // 换行
		fileName = "D:/createFile1"; // 解压缩后文件名
		TestReadZiP.upzipFile(zipFileName, fileName);// 调用方法解压缩文件或目录
	}
}


评论关闭
评论 还能输入200
评论关闭
评论 还能输入200
资料加载中...
已关注 , 取消