Java压缩技术(三) ZIP解压缩——Java原生实现
原文:http://snowolf.iteye.com/blog/642492
JavaEye的朋友跟我说:“你一口气把ZIP压缩和解压缩都写到一个帖子里,我看起来很累,不如分开好阅读”。ok,面向读者需求,我做调整,这里单说ZIP解压缩!
解压缩与压缩运作方式相反,原理大抵相同,由ZipInputStream通过read方法对数据解压,同时需要通过CheckedInputStream设置冗余校验码,如:
- CheckedInputStream cis = new CheckedInputStream(new FileInputStream(
- srcFile), new CRC32());
- ZipInputStream zis = new ZipInputStream(cis);
需要注意的是,在构建解压文件时,需要考虑目录的自动创建,这里通过递归方式逐层创建父目录,如下所示:
- /**
- * 文件探针
- *
- *
- * 当父目录不存在时,创建目录!
- *
- *
- * @param dirFile
- */
- private static void fileProber(File dirFile) {
- File parentFile = dirFile.getParentFile();
- if (!parentFile.exists()) {
- // 递归寻找上级目录
- fileProber(parentFile);
- parentFile.mkdir();
- }
- }
在压缩的时候,我们是将一个一个文件作为压缩添加项(ZipEntry)添加至压缩包中,解压缩就要将一个一个压缩项从压缩包中提取出来,如下所示:
- /**
- * 文件 解压缩
- *
- * @param destFile
- * 目标文件
- * @param zis
- * ZipInputStream
- * @throws Exception
- */
- private static void decompress(File destFile, ZipInputStream zis)
- throws Exception {
- ZipEntry entry = null;
- while ((entry = zis.getNextEntry()) != null) {
- // 文件
- String dir = destFile.getPath() + File.separator + entry.getName();
- File dirFile = new File(dir);
- // 文件检查
- fileProber(dirFile);
- if (entry.isDirectory()){
- dirFile.mkdirs();
- } else {
- decompressFile(dirFile, zis);
- }
- zis.closeEntry();
- }
- }
最核心的解压缩实现,其实与压缩实现非常相似,代码如下所示:
- /**
- * 文件解压缩
- *
- * @param destFile
- * 目标文件
- * @param zis
- * ZipInputStream
- * @throws Exception
- */
- private static void decompressFile(File destFile, ZipInputStream zis)
- throws Exception {
- BufferedOutputStream bos = new BufferedOutputStream(
- new FileOutputStream(destFile));
- int count;
- byte data[] = new byte[BUFFER];
- while ((count = zis.read(data, 0, BUFFER)) != -1) {
- bos.write(data, 0, count);
- }
- bos.close();
- }
来个完整的解压缩实现,代码如下:
- /**
- * 2010-4-12
- */
- package org.zlex.commons.io;
- import java.io.BufferedInputStream;
- import java.io.BufferedOutputStream;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.util.zip.CRC32;
- import java.util.zip.CheckedInputStream;
- import java.util.zip.CheckedOutputStream;
- import java.util.zip.ZipEntry;
- import java.util.zip.ZipInputStream;
- import java.util.zip.ZipOutputStream;
- /**
- * ZIP压缩工具
- *
- * @author 梁栋
- * @since 1.0
- */
- public class ZipUtils {
- public static final String EXT = ".zip";
- private static final String BASE_DIR = "";
- private static final String PATH = File.separator;
- private static final int BUFFER = 1024;
- /**
- * 文件 解压缩
- *
- * @param srcPath
- * 源文件路径
- *
- * @throws Exception
- */
- public static void decompress(String srcPath) throws Exception {
- File srcFile = new File(srcPath);
- decompress(srcFile);
- }
- /**
- * 解压缩
- *
- * @param srcFile
- * @throws Exception
- */
- public static void decompress(File srcFile) throws Exception {
- String basePath = srcFile.getParent();
- decompress(srcFile, basePath);
- }
- /**
- * 解压缩
- *
- * @param srcFile
- * @param destFile
- * @throws Exception
- */
- public static void decompress(File srcFile, File destFile) throws Exception {
- CheckedInputStream cis = new CheckedInputStream(new FileInputStream(
- srcFile), new CRC32());
- ZipInputStream zis = new ZipInputStream(cis);
- decompress(destFile, zis);
- zis.close();
- }
- /**
- * 解压缩
- *
- * @param srcFile
- * @param destPath
- * @throws Exception
- */
- public static void decompress(File srcFile, String destPath)
- throws Exception {
- decompress(srcFile, new File(destPath));
- }
- /**
- * 文件 解压缩
- *
- * @param srcPath
- * 源文件路径
- * @param destPath
- * 目标文件路径
- * @throws Exception
- */
- public static void decompress(String srcPath, String destPath)
- throws Exception {
- File srcFile = new File(srcPath);
- decompress(srcFile, destPath);
- }
- /**
- * 文件 解压缩
- *
- * @param destFile
- * 目标文件
- * @param zis
- * ZipInputStream
- * @throws Exception
- */
- private static void decompress(File destFile, ZipInputStream zis)
- throws Exception {
- ZipEntry entry = null;
- while ((entry = zis.getNextEntry()) != null) {
- // 文件
- String dir = destFile.getPath() + File.separator + entry.getName();
- File dirFile = new File(dir);
- // 文件检查
- fileProber(dirFile);
- if (entry.isDirectory()) {
- dirFile.mkdirs();
- } else {
- decompressFile(dirFile, zis);
- }
- zis.closeEntry();
- }
- }
- /**
- * 文件探针
- *
- *
- * 当父目录不存在时,创建目录!
- *
- *
- * @param dirFile
- */
- private static void fileProber(File dirFile) {
- File parentFile = dirFile.getParentFile();
- if (!parentFile.exists()) {
- // 递归寻找上级目录
- fileProber(parentFile);
- parentFile.mkdir();
- }
- }
- /**
- * 文件解压缩
- *
- * @param destFile
- * 目标文件
- * @param zis
- * ZipInputStream
- * @throws Exception
- */
- private static void decompressFile(File destFile, ZipInputStream zis)
- throws Exception {
- BufferedOutputStream bos = new BufferedOutputStream(
- new FileOutputStream(destFile));
- int count;
- byte data[] = new byte[BUFFER];
- while ((count = zis.read(data, 0, BUFFER)) != -1) {
- bos.write(data, 0, count);
- }
- bos.close();
- }
- }
其实,理解了ZIP的工作原理,这些代码看起来很好懂!
把刚才做的压缩文件再用上述代码解开看看,测试用例如下:
- /**
- * 2010-4-12
- */
- package org.zlex.commons.io;
- import static org.junit.Assert.*;
- import org.junit.Test;
- /**
- *
- * @author 梁栋
- * @version 1.0
- * @since 1.0
- */
- public class ZipUtilsTest {
- /**
- *
- */
- @Test
- public void test() throws Exception {
- // 解压到指定目录
- ZipUtils.decompress("d:\\f.txt.zip", "d:\\ff");
- // 解压到当前目录
- ZipUtils.decompress("d:\\fd.zip");
- }
- }
完整代码详见附件!
java原生的ZIP实现虽然在压缩时会因与系统字符集不符产生中文乱码,但在解压缩后,字符集即可恢复。
除了java原生的ZIP实现外,commons和ant也提供了相应的ZIP算法实现,有机会我再一一介绍!
Java压缩技术(三) ZIP解压缩——Java原生实现的更多相关文章
- Java压缩技术(二) ZIP压缩——Java原生实现
原文:http://snowolf.iteye.com/blog/642298 去年整理了一篇ZLib算法Java实现(Java压缩技术(一) ZLib),一直惦记却没时间补充.今天得空,整理一下ZI ...
- Java压缩/解压.zip、.tar.gz、.tar.bz2(支持中文)
本文介绍Java压缩/解压.zip..tar.gz..tar.bz2的方式. 对于zip文件:使用java.util.zip.ZipEntry 和 java.util.zip.ZipFile,通过设置 ...
- Java基础:三步学会Java Socket编程
Java基础:三步学会Java Socket编程 http://tech.163.com 2006-04-10 09:17:18 来源: java-cn 网友评论11 条 论坛 第一步 ...
- Java压缩技术的学习
由于工作的需要,经常要手动去打上线安装包,为了方便,自己写程序去帮助打包.使用过Unix或者Linux的人都基本上都用过tar打包以及gzip压缩,但在Windows下使用得最多的压缩还是RAR和Zi ...
- java 压缩技术
package zip; import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStr ...
- JAVA压缩解压ZIP文件,中文乱码还需要ANT.JAR包
package zip; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStrea ...
- java 压缩和解压zip包
网上有关压缩和解压zip包的博文一大堆,我随便找了一个.看了看,依照自己的须要改动了一下,与各位分享一下,希望各位大神指正: package com.wangpeng.utill; import ja ...
- Java虚拟机(三):Java 类的加载机制
1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...
- 赶紧收藏!王者级别的Java多线程技术笔记,我java小菜鸡愿奉你为地表最强!
Java多线程技术概述 介绍多线程之前要介绍线程,介绍线程则离不开进程. 首先 , 进程 :是一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元: 线程:就 ...
随机推荐
- 2016.01.05 DOM笔记(一) 查找元素
DOM节点的种类 元素和标签是一个意思,例如<body>标签或者称为<body>元素 节点DOM的节点分为三类 元素节点,文本节点,属性节点 例如 <div id=‘b ...
- 【sqli-labs】 less54 GET -Challenge -Union -10 queries allowed -Variation1 (GET型 挑战 联合查询 只允许10次查询 变化1)
尝试的次数只有10次 http://192.168.136.128/sqli-labs-master/Less-54/index.php?id=1' 单引号报错,错误信息没有显示 加注释符页面恢复正常 ...
- Codeforces_732D_(二分贪心)
D. Exams time limit per test 1 second memory limit per test 256 megabytes input standard input outpu ...
- Linux命令(文本编辑器)
vi和vim编辑器:有插入模式,一般模式,地行模式 一班模式通过(i.a.o.I.A.O)键--->进入插入模式 插入模式(按Esc键退出)---->j进入一班模式 ...
- Python os模块和time模块 day4
一.os模块 print(os.listdir(r'/Users/smh/Desktop/整理'))#os.listdir() 列出某个目录下面的文件夹/文件 print(os.path.isfile ...
- Oracle,sqlserver,mySQl的区别和联系:
1.日期处理方式 2.对保留字和关键字的处理方式: Oracle,sqlserver,mySQl的保留字不可以用作列字段,关键字可以,但他们对关键字的处理方式又不同: Oracle:关键字作为列时:用 ...
- Notepad++运行JAVA代码
第一种方法: 工具栏->运行 点击后选择运行 1.在运行窗口中输入: cmd /k javac "$(FULL_CURRENT_PATH)" & echo 编译成功 ...
- 找零钱的算法实现(Java)
简单的算法 基本思路就是将面值从大到小统计(外循环), 若当前金额大于某面值, 则当前金额减掉该面值, 并将面值对应张数+1, 继续往下判断(内循环) public void Change(int m ...
- Python-基本语法元素
#TempConvert.py TempStr = input("请输入带有符号的温度值: ") if TempStr[-1] in ['F', 'f']: C = (eval(T ...
- linux修改mysql表结构
增加字段: alter table [tablename] add [字段名] [字段类型] first(首位); alter table [tablename] add [字段名] [字段类型] a ...