Java 解压 zip

本文介绍了一个使用Java进行ZIP文件解压的实用案例,通过解析ZIP文件并将其内容解压到指定目录,展示了如何读取ZIP条目、处理文件和目录结构,以及使用IO流复制文件内容。
package cn.jbolt.writefile;

import java.io.File;
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;

public class UnpackZip {

	private static final int BUFFER_SIZE = 2 * 1024;

	private static final String filePath = "F:\\demo.zip";

	private static final String destDirPath = "F:\\demo";

	public static void main(String[] args) throws Exception {
		unZip(new File(filePath), destDirPath);
	}

	public static void unZip(File srcFile, String destDirPath) throws RuntimeException {
		long start = System.currentTimeMillis(); // 判断源文件是否存在
		if (!srcFile.exists()) {
			throw new RuntimeException(srcFile.getPath() + "所指文件不存在");
		}
		// 开始解压
		ZipFile zipFile = null;
		try {
			zipFile = new ZipFile(srcFile);
			Enumeration<?> entries = zipFile.entries();
			while (entries.hasMoreElements()) {
				ZipEntry entry = (ZipEntry) entries.nextElement();
				System.out.println("解压" + entry.getName());
				// 如果是文件夹,就创建个文件夹
				if (entry.isDirectory()) {
					String dirPath = destDirPath + "/" + entry.getName();
					File dir = new File(dirPath);
					dir.mkdirs();
				} else {
					// 如果是文件,就先创建一个文件,然后用io流把内容copy过去
					File targetFile = new File(destDirPath + "/" + entry.getName());
					// 保证这个文件的父文件夹必须要存在
					if (!targetFile.getParentFile().exists()) {
						targetFile.getParentFile().mkdirs();
					}
					targetFile.createNewFile();
					// 将压缩文件内容写入到这个文件中
					InputStream is = zipFile.getInputStream(entry);
					FileOutputStream fos = new FileOutputStream(targetFile);
					int len;
					byte[] buf = new byte[BUFFER_SIZE];
					while ((len = is.read(buf)) != -1) {
						fos.write(buf, 0, len);
					}
					// 关流顺序,先打开的后关闭
					fos.close();
					is.close();
				}
			}
			long end = System.currentTimeMillis();
			System.out.println("解压完成,耗时:" + (end - start) + " ms");
		} catch (Exception e) {
			throw new RuntimeException("unzip error from ZipUtils", e);
		} finally {
			if (zipFile != null) {
				try {
					zipFile.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

	}

}

 

程序测试可用,直接导入到工程就可以,bat文件跟shell文件是用于在window跟linux上直接执行的脚本 我把开发的配置文档附上: 1.程序为定时任务,任务执行时间在bin目录下的配置文件mergeFilleUtil.properties中配置,在配置文件中,TASK_PERIOD表示任务执行时间间隔,单位为妙,如一天的时间间隔配置是86400,TASK_BEGIN_HOUR表示任务开始的小时时间,比如9点,TASK_BEGIN_MINUTE表任务开始的分钟,比如30分。 2. 程序用log4j记录日志,日志分正常信息跟错误信息两个级别,日志文件存放在log4j文件夹下。考虑到文件很多,日志、移动文件每、移动1000个记录一次,合并、删除文件每合并、删除50000个记录一次, 3. 启动任务前需配置文件合并的路径,本程序需配置的路径如下: 1). PROVINCE_DIR:原始文件存放的路径,必须配置到省的上一级路径,比如存放安徽省的文件路径为E:\test\rootfile\anhui,那么文件的路径必须配置为E:\test\rootfile,否则不能正确显示合并结果; 2). UN_ZIP_PATH:存放后的文件的路径; 3). OUT_PATH:存放合并后的文件路径; 4). DONE_FILE_PATH:存放已经处理过的文件; 5). DELETE_PATH:配置程序运行结束后欲删除文件的路径,如想删除多个文件夹下的文件,路径之间用逗号隔开,勿加空格,比如:E:\test\rootfile,E:\test\unZip; 4. 注意事项: 本合并程序处理文件的逻辑如下: 程序每次都去PROVINCE_DIR文件下去,将后的文件存放到UN_ZIP_PATH下,之后程序启动合并程序合并UN_ZIP_PATH下文件,将合并后的文件按照省份名称存放到OUT_PATH,一个省一个文件。当合并结束后,程序将PROVINCE_DIR路径下的文件移动到DONE_FILE_PATH下,并且删除PROVINCE_DIR跟UN_ZIP_PATH下文件,这样保证程序每次运行PROVINCE_DIR文件夹下的文件跟UN_ZIP_PATH下的文件都是最新未处理过的,避免了不断判断文件历史记录所带来的大量时间消耗。 所以为了保证文件跟合并的正确性,必须配置好DELETE_PATH路径下的文件,否则合并后的结果是不准确的。
<think> 首先,用户的问题是:“我想查找使用Javazip文件的方法 请问Java实现zip文件的方法”。这是一个关于如何在JavaZIP文件的具体查询。 根据系统级指令: - 所有行内数学表达式必须使用 $...$ 格式(但在这个上下文中,可能没有数学表达式)。 - 独立公式使用 $$...$$ 格式(同样,可能不需要)。 - LaTeX语法正确(确保在回答中正确使用)。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,如 [^1]。 - 回答结构清晰,帮助用户逐步决问题,保证真实可靠。 用户提供了几个参考引用: - 引用[1]: 关于Java实现ZIP文件缩与缩的详细文章。 - 引用[2]: 提到Java实现zip文件缩与缩全。 - 引用[3]: 关于javazip文件,包括添加依赖。 从这些引用中,我可以提取相关信息来构建回答。用户的核心需求是实现ZIP文件的方法。 结构化我的回答: 1. **引言**:简要介绍JavaZIP文件的基本方法。 2. **逐步释**:提供一个清晰的步骤指南,包括代码示例。 3. **代码示例**:使用引用中的信息来展示一个简单的Java代码示例。 4. **注意事项**:讨论可能的错误处理、文件名编码问题等。 5. **生成相关问题**:在最后添加相关问题。 6. **引用标识**:在相关部分末尾添加引用标识。 关键点从引用: - 使用 `java.util.zip` 包中的 `ZipInputStream`。 - 创建 `ZipEntry` 来处理每个文件。 - 读取并写入文件。 - 引用[3]提到使用第三方库如Apache Commons VFS,但标准方法是使用 `java.util.zip`。 标准方法步骤: 1. 创建一个 `FileInputStream` 指向ZIP文件。 2. 创建一个 `ZipInputStream` 包装它。 3. 遍历每个 `ZipEntry`。 4. 对于每个条目,读取数据并写入到输出文件。 5. 关闭流。 代码示例: ```java import java.io.*; import java.util.zip.*; public class UnzipExample { public static void main(String[] args) { String zipFilePath = "example.zip"; String destDirectory = "output_folder"; unzip(zipFilePath, destDirectory); } public static void unzip(String zipFilePath, String destDirectory) { File destDir = new File(destDirectory); if (!destDir.exists()) { destDir.mkdir(); } try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath))) { ZipEntry entry = zipIn.getNextEntry(); while (entry != null) { String filePath = destDirectory + File.separator + entry.getName(); if (!entry.isDirectory()) { // 如果条目是文件,则提取 extractFile(zipIn, filePath); } else { // 如果条目是目录,则创建目录 File dir = new File(filePath); dir.mkdirs(); } zipIn.closeEntry(); entry = zipIn.getNextEntry(); } } catch (IOException e) { e.printStackTrace(); } } private static void extractFile(ZipInputStream zipIn, String filePath) throws IOException { try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath))) { byte[] bytesIn = new byte[4096]; int read; while ((read = zipIn.read(bytesIn)) != -1) { bos.write(bytesIn, 0, read); } } } } ``` 添加引用标识:在释或代码后添加 [^1], [^2], [^3]。 生成相关问题: - 类似于示例中的快速排序问题。 - 例如: 1. 如何处理ZIP文件中的文件名编码问题? 2. Java中有哪些高级ZIP处理库? 3. 如何缩文件到ZIP格式? 确保使用中文回答。 最终回答结构: - 开头:介绍方法。 - 步骤释和代码。 - 注意事项。 - 相关问题。 </think>以下我将详细释如何在Java中实现ZIP文件的方法。Java提供了标准库 `java.util.zip` 来处理ZIP文件格式,核心类是 `ZipInputStream` 和 `ZipEntry`。整个过程包括读取ZIP文件、遍历缩条目、提取并写入后的文件。我会逐步说明操作步骤,并提供完整的代码示例。方法基于Java标准库,无需额外依赖(除非需要高级功能)[^1][^2]。 ### 步骤详JavaZIP文件 1. **初始化输入流**: - 使用 `ZipInputStream` 包装 `FileInputStream`,指向要ZIP文件。 - `ZipInputStream` 负责读取缩数据流。 2. **遍历缩条目**: - 调用 `getNextEntry()` 方法获取每个 `ZipEntry`(代表ZIP内的一个文件或目录)。 - 检查条目类型:如果是目录,则创建对应文件夹;如果是文件,则准备写入。 3. **提取并写入文件**: - 对于文件条目,创建输出流(如 `FileOutputStream`)写入后的数据。 - 使用缓冲区读取数据块(例如4096字节),提高效率。 4. **关闭资源**: - 完成每个条目后,调用 `closeEntry()`。 - 最后关闭所有流,确保资源释放。 ### 完整代码示例 以下是一个简单的Java程序,实现ZIP文件到指定目录: ```java import java.io.*; import java.util.zip.*; public class ZipUnzipExample { public static void main(String[] args) { String zipFilePath = "example.zip"; // ZIP文件路径 String destDir = "unzipped"; // 目标目录 unzip(zipFilePath, destDir); // 调用方法 } public static void unzip(String zipFilePath, String destDir) { File destDirectory = new File(destDir); // 创建目标目录(如果不存在) if (!destDirectory.exists()) { destDirectory.mkdir(); } try (ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath))) { ZipEntry entry = zipIn.getNextEntry(); // 获取第一个条目 // 遍历所有条目 while (entry != null) { String filePath = destDir + File.separator + entry.getName(); if (!entry.isDirectory()) { // 处理文件:写入数据 extractFile(zipIn, filePath); } else { // 处理目录:创建文件夹 File dir = new File(filePath); dir.mkdirs(); } zipIn.closeEntry(); // 关闭当前条目 entry = zipIn.getNextEntry(); // 获取下一个条目 } } catch (IOException e) { e.printStackTrace(); // 处理异常(实际项目中应更详细) } } private static void extractFile(ZipInputStream zipIn, String filePath) throws IOException { // 确保父目录存在 File parentFile = new File(filePath).getParentFile(); if (!parentFile.exists()) { parentFile.mkdirs(); } // 写入文件数据 try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath))) { byte[] buffer = new byte[4096]; // 缓冲区大小 int bytesRead; while ((bytesRead = zipIn.read(buffer)) != -1) { bos.write(buffer, 0, bytesRead); } } } } ``` ### 关键注意事项 - **错误处理**:在实际应用中,应添加更健壮的异常处理(如捕获 `ZipException`),避免ZIP损坏导致程序崩溃[^1]。 - **文件名编码问题**:如果ZIP文件包含非ASCII字符(如中文文件名),可能需要指定编码: ```java ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath), StandardCharsets.UTF_8); ``` - **安全考虑**:验证条目名称防止路径遍历攻击(例如,确保 `entry.getName()` 不以 `../` 开头)。 - **第三方库**:对于复杂需求(如加密ZIP),可使用Apache Commons Compress或`commons-vfs2`: ```xml <!-- Maven依赖示例 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId> <version>1.25.0</version> </dependency> ``` 引用[^3]提到使用Apache Commons VFS,但标准 `java.util.zip` 已满足基本需求。 ### 性能优化建议 - **缓冲区大小**:调整缓冲区(如 `new byte[8192]`)可提升大文件处理速度。 - **多线程**:对于大型ZIP,可使用 `ExecutorService` 并行处理多个条目。 - **资源管理**:始终使用 try-with-resources(如示例代码)自动关闭流。 通过上述方法,您可以高效实现ZIP文件的[^1][^2]。如需处理特定场景(如加密文件),请参考Java文档或第三方库。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值