Java实现压缩和解压zip和jar

本文介绍了一个Java实现的压缩与解压缩工具类,支持ZIP和JAR格式的文件压缩,并提供了详细的代码示例。文章展示了如何使用该工具类进行文件的压缩和解压缩操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * 压缩类型枚举
 * 
 * @author Log
 *
 */
enum CompressType {
//	GZIP是用于UNIX系统的文件压缩,在Linux中经常会使用到*.gz的文件,就是GZIP格式
	ZIP, JAR, GZIP
}

public class ZipUtils {

	public static void main(String[] args) {
//		compress(CompressType.ZIP);
		unZip("压缩.zip", "压缩后");
//		unZip("压缩.jar", "压缩后jar");
	}

	public static void compress(CompressType type) {
		if (type == CompressType.ZIP) {
			zip("压缩", "压缩.zip", CompressType.ZIP);
		} else if (type == CompressType.JAR) {
			zip("压缩", "压缩.jar", CompressType.JAR);
		}
	}

	public static void zip(String inputFile, String outputFile, CompressType type) {
		zip(new File(inputFile), new File(outputFile), type);
	}

	/**
	 * 初始化压缩包信息并开始进行压缩
	 * 
	 * @param inputFile  需要压缩的文件或文件夹
	 * @param outputFile 压缩后的文件
	 * @param type       压缩类型
	 */
	public static void zip(File inputFile, File outputFile, CompressType type) {
		ZipOutputStream zos = null;
		try {
			if (type == CompressType.ZIP) {
				zos = new ZipOutputStream(new FileOutputStream(outputFile));
			} else if (type == CompressType.JAR) {
				zos = new JarOutputStream(new FileOutputStream(outputFile));
			} else {
				zos = new ZipOutputStream(new FileOutputStream(outputFile));
			}
			// 设置压缩包注释
			zos.setComment("From Log");
			zipFile(zos, inputFile, null);
			System.err.println("压缩完成!");
		} catch (IOException e) {
			e.printStackTrace();
			System.err.println("压缩失败!");
		} finally {
			if (zos != null) {
				try {
					zos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 如果是单个文件,那么就直接进行压缩。如果是文件夹,那么递归压缩所有文件夹里的文件
	 * 
	 * @param zos       压缩输出流
	 * @param inputFile 需要压缩的文件
	 * @param path      需要压缩的文件在压缩包里的路径
	 */
	public static void zipFile(ZipOutputStream zos, File inputFile, String path) {
		if (inputFile.isDirectory()) {
			// 记录压缩包中文件的全路径
			String p = null;
			File[] fileList = inputFile.listFiles();
			for (int i = 0; i < fileList.length; i++) {
				File file = fileList[i];
				// 如果路径为空,说明是根目录
				if (path == null || path.isEmpty()) {
					p = file.getName();
				} else {
					p = path + File.separator + file.getName();
				}
				// 打印路径
				System.out.println(p);
				// 如果是目录递归调用,直到遇到文件为止
				zipFile(zos, file, p);
			}
		} else {
			zipSingleFile(zos, inputFile, path);
		}
	}

	/**
	 * 压缩单个文件到指定压缩流里
	 * 
	 * @param zos       压缩输出流
	 * @param inputFile 需要压缩的文件
	 * @param path      需要压缩的文件在压缩包里的路径
	 * @throws FileNotFoundException
	 */
	public static void zipSingleFile(ZipOutputStream zos, File inputFile, String path) {
		try {
			InputStream in = new FileInputStream(inputFile);
			zos.putNextEntry(new ZipEntry(path));
			write(in, zos);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 解压压缩包到指定目录
	 * 
	 * @param inputFile
	 * @param outputFile
	 */
	public static void unZip(String inputFile, String outputFile) {
		unZip(new File(inputFile), new File(outputFile));
	}

	/**
	 * 解压压缩包到指定目录
	 * 
	 * @param inputFile
	 * @param outputFile
	 */
	public static void unZip(File inputFile, File outputFile) {
		if (!outputFile.exists()) {
			outputFile.mkdirs();
		}

		ZipFile zipFile = null;
		ZipInputStream zipInput = null;
		ZipEntry entry = null;
		OutputStream output = null;
		InputStream input = null;
		File file = null;
		try {
			zipFile = new ZipFile(inputFile);
			zipInput = new ZipInputStream(new FileInputStream(inputFile));
			String path = outputFile.getAbsolutePath() + File.separator;
			while ((entry = zipInput.getNextEntry()) != null) {
				// 从压缩文件里获取指定已压缩文件的输入流
				input = zipFile.getInputStream(entry);

				// 拼装压缩后真实文件路径
				String fileName = path + entry.getName();
				System.out.println(fileName);

				// 创建文件缺失的目录(不然会报异常:找不到指定文件)
				file = new File(fileName.substring(0, fileName.lastIndexOf(File.separator)));
				file.mkdirs();

				// 创建文件输出流
				output = new FileOutputStream(fileName);

				// 写出解压后文件数据
				write(input, output);
				output.close();
			}
		} catch (ZipException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (output != null) {
					output.close();
				}

				if (zipInput != null) {
					zipInput.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 从输入流写入到输出流的方便方法 【注意】这个函数只会关闭输入流,且读写完成后会调用输出流的flush()函数,但不会关闭输出流!
	 * 
	 * @param input
	 * @param output
	 */
	private static void write(InputStream input, OutputStream output) {
		int len = -1;
		byte[] buff = new byte[1024];
		try {
			while ((len = input.read(buff)) != -1) {
				output.write(buff, 0, len);
			}
			output.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				input.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值