Java压缩技术(二) ZIP压缩——Java原生实现

转载自   Java压缩技术(二) ZIP压缩——Java原生实现

查过相关资料后才知道,ZIP应该算作归档类的压缩算法,每一门学科都可深可浅! 

闲言少叙,先说ZIP压缩。 
zip压缩需要通过ZipOutputStream 执行write方法将压缩数据写到指定输出流中。 
注意,这里应先使用CheckedOutputStream 指定文件校验算法。(通常使用CRC32算法)。代码如下所示: 

Java代码
  1. CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(destPath), new CRC32());  
  2. ZipOutputStream zos = new ZipOutputStream(cos);  

接下来,需要将待压缩文件以ZipEntry的方式追加到压缩文件中,如下所示: 
Java代码 
  1.  /** 
  2.  * 压缩包内文件名定义 
  3.  *  
  4.  * <pre> 
  5.  * 如果有多级目录,那么这里就需要给出包含目录的文件名 
  6.  * 如果用WinRAR打开压缩包,中文名将显示为乱码 
  7.  * </pre> 
  8.  */  
  9. ZipEntry entry = new ZipEntry(dir + file.getName());  
  10.   
  11. zos.putNextEntry(entry);  

ZipEntry就是压缩包中的每一个实体! 
完成上述准备后,就可以执行压缩操作了。实际上,就是执行ZipOutputStream类的write方法,如下所示: 
Java代码 
  1. BufferedInputStream bis = new BufferedInputStream(new FileInputStream(  
  2.         file));  
  3.   
  4. int count;  
  5. byte data[] = new byte[BUFFER];  
  6. while ((count = bis.read(data, 0, BUFFER)) != -1) {  
  7.     zos.write(data, 0, count);  
  8. }  
  9. bis.close();  

当然,如果待添加的压缩项是一个目录。那么,需要通过递归的方式指定最终的压缩项。 
如果要添加一个空目录,注意使用符号"/"(String PATH="/";)作为添加项名字结尾符!  

递归构建目录压缩,代码如下: 
Java代码 
  1. /** 
  2.  * 压缩 
  3.  *  
  4.  * @param srcFile 
  5.  *            源路径 
  6.  * @param zos 
  7.  *            ZipOutputStream 
  8.  * @param basePath 
  9.  *            压缩包内相对路径 
  10.  * @throws Exception 
  11.  */  
  12. private static void compress(File srcFile, ZipOutputStream zos,  
  13.         String basePath) throws Exception {  
  14.     if (srcFile.isDirectory()) {  
  15.         compressDir(srcFile, zos, basePath);  
  16.     } else {  
  17.         compressFile(srcFile, zos, basePath);  
  18.     }  
  19. }  
  20.   
  21. /** 
  22.  * 压缩目录 
  23.  *  
  24.  * @param dir 
  25.  * @param zos 
  26.  * @param basePath 
  27.  * @throws Exception 
  28.  */  
  29. private static void compressDir(File dir, ZipOutputStream zos,  
  30.         String basePath) throws Exception {  
  31.   
  32.     File[] files = dir.listFiles();  
  33.   
  34.     // 构建空目录  
  35.     if (files.length < 1) {  
  36.         ZipEntry entry = new ZipEntry(basePath + dir.getName() + PATH);  
  37.   
  38.         zos.putNextEntry(entry);  
  39.         zos.closeEntry();  
  40.     }  
  41.   
  42.     for (File file : files) {  
  43.         // 递归压缩  
  44.         compress(file, zos, basePath + dir.getName() + PATH);  
  45.     }  
  46. }  
x是一个空目录,用WinRAR打开后,可以看到这个目录下还有一个空文件名文件!  
来个完整的压缩实现,代码如下所示: 
Java代码 
  1. /** 
  2.  * 2010-4-12 
  3.  */  
  4. package org.zlex.commons.io;  
  5.   
  6. import java.io.BufferedInputStream;  
  7. import java.io.BufferedOutputStream;  
  8. import java.io.File;  
  9. import java.io.FileInputStream;  
  10. import java.io.FileOutputStream;  
  11. import java.util.zip.CRC32;  
  12. import java.util.zip.CheckedInputStream;  
  13. import java.util.zip.CheckedOutputStream;  
  14. import java.util.zip.ZipEntry;  
  15. import java.util.zip.ZipInputStream;  
  16. import java.util.zip.ZipOutputStream;  
  17.   
  18. /** 
  19.  * ZIP压缩工具 
  20.  *  
  21.  * @author  <a href="mailto:zlex.dongliang@gmail.com">梁栋</a>    
  22.  * @since 1.0 
  23.  */  
  24. public class ZipUtils {  
  25.   
  26.     public static final String EXT = ".zip";  
  27.     private static final String BASE_DIR = "";  
  28.   
  29.     // 符号"/"用来作为目录标识判断符  
  30.     private static final String PATH = "/";  
  31.     private static final int BUFFER = 1024;  
  32.   
  33.     /** 
  34.      * 压缩 
  35.      *  
  36.      * @param srcFile 
  37.      * @throws Exception 
  38.      */  
  39.     public static void compress(File srcFile) throws Exception {  
  40.         String name = srcFile.getName();  
  41.         String basePath = srcFile.getParent();  
  42.         String destPath = basePath + name + EXT;  
  43.         compress(srcFile, destPath);  
  44.     }  
  45.   
  46.     /** 
  47.      * 压缩 
  48.      *  
  49.      * @param srcFile 
  50.      *            源路径 
  51.      * @param destPath 
  52.      *            目标路径 
  53.      * @throws Exception 
  54.      */  
  55.     public static void compress(File srcFile, File destFile) throws Exception {  
  56.   
  57.         // 对输出文件做CRC32校验  
  58.         CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(  
  59.                 destFile), new CRC32());  
  60.   
  61.         ZipOutputStream zos = new ZipOutputStream(cos);  
  62.   
  63.         compress(srcFile, zos, BASE_DIR);  
  64.   
  65.         zos.flush();  
  66.         zos.close();  
  67.     }  
  68.   
  69.     /** 
  70.      * 压缩文件 
  71.      *  
  72.      * @param srcFile 
  73.      * @param destPath 
  74.      * @throws Exception 
  75.      */  
  76.     public static void compress(File srcFile, String destPath) throws Exception {  
  77.         compress(srcFile, new File(destPath));  
  78.     }  
  79.   
  80.     /** 
  81.      * 压缩 
  82.      *  
  83.      * @param srcFile 
  84.      *            源路径 
  85.      * @param zos 
  86.      *            ZipOutputStream 
  87.      * @param basePath 
  88.      *            压缩包内相对路径 
  89.      * @throws Exception 
  90.      */  
  91.     private static void compress(File srcFile, ZipOutputStream zos,  
  92.             String basePath) throws Exception {  
  93.         if (srcFile.isDirectory()) {  
  94.             compressDir(srcFile, zos, basePath);  
  95.         } else {  
  96.             compressFile(srcFile, zos, basePath);  
  97.         }  
  98.     }  
  99.   
  100.     /** 
  101.      * 压缩 
  102.      *  
  103.      * @param srcPath 
  104.      * @throws Exception 
  105.      */  
  106.     public static void compress(String srcPath) throws Exception {  
  107.         File srcFile = new File(srcPath);  
  108.   
  109.         compress(srcFile);  
  110.     }  
  111.   
  112.     /** 
  113.      * 文件压缩 
  114.      *  
  115.      * @param srcPath 
  116.      *            源文件路径 
  117.      * @param destPath 
  118.      *            目标文件路径 
  119.      *  
  120.      */  
  121.     public static void compress(String srcPath, String destPath)  
  122.             throws Exception {  
  123.         File srcFile = new File(srcPath);  
  124.   
  125.         compress(srcFile, destPath);  
  126.     }  
  127.   
  128.     /** 
  129.      * 压缩目录 
  130.      *  
  131.      * @param dir 
  132.      * @param zos 
  133.      * @param basePath 
  134.      * @throws Exception 
  135.      */  
  136.     private static void compressDir(File dir, ZipOutputStream zos,  
  137.             String basePath) throws Exception {  
  138.   
  139.         File[] files = dir.listFiles();  
  140.   
  141.         // 构建空目录  
  142.         if (files.length < 1) {  
  143.             ZipEntry entry = new ZipEntry(basePath + dir.getName() + PATH);  
  144.   
  145.             zos.putNextEntry(entry);  
  146.             zos.closeEntry();  
  147.         }  
  148.   
  149.         for (File file : files) {  
  150.   
  151.             // 递归压缩  
  152.             compress(file, zos, basePath + dir.getName() + PATH);  
  153.   
  154.         }  
  155.     }  
  156.   
  157.     /** 
  158.      * 文件压缩 
  159.      *  
  160.      * @param file 
  161.      *            待压缩文件 
  162.      * @param zos 
  163.      *            ZipOutputStream 
  164.      * @param dir 
  165.      *            压缩文件中的当前路径 
  166.      * @throws Exception 
  167.      */  
  168.     private static void compressFile(File file, ZipOutputStream zos, String dir)  
  169.             throws Exception {  
  170.   
  171.         /** 
  172.          * 压缩包内文件名定义 
  173.          *  
  174.          * <pre> 
  175.          * 如果有多级目录,那么这里就需要给出包含目录的文件名 
  176.          * 如果用WinRAR打开压缩包,中文名将显示为乱码 
  177.          * </pre> 
  178.          */  
  179.         ZipEntry entry = new ZipEntry(dir + file.getName());  
  180.   
  181.         zos.putNextEntry(entry);  
  182.   
  183.         BufferedInputStream bis = new BufferedInputStream(new FileInputStream(  
  184.                 file));  
  185.   
  186.         int count;  
  187.         byte data[] = new byte[BUFFER];  
  188.         while ((count = bis.read(data, 0, BUFFER)) != -1) {  
  189.             zos.write(data, 0, count);  
  190.         }  
  191.         bis.close();  
  192.   
  193.         zos.closeEntry();  
  194.     }  
  195.   
  196. }  

来做个简单的测试: 
Java代码 
  1. import static org.junit.Assert.*;  
  2.   
  3. import org.junit.Test;  
  4.   
  5. /** 
  6.  *  
  7.  * @author 梁栋 
  8.  * @version 1.0 
  9.  * @since 1.0 
  10.  */  
  11. public class ZipUtilsTest {  
  12.   
  13.     /** 
  14.      *   
  15.      */  
  16.     @Test  
  17.     public void test() throws Exception {  
  18.         // 压缩文件  
  19.         ZipUtils.compress("d:\\f.txt");  
  20.         // 压缩目录  
  21.         ZipUtils.compress("d:\\fd");  
  22.     }  
  23. }  
现在用WinRAR打开看看,是不是效果几乎一致?
当然,上述代码有所不足之处主要是中文名称乱码问题。用java原生ZIP实现压缩后得到的压缩包,与系统的字符集不同,文件/目录名将出现乱码。这是所有归档压缩都会遇到的问题。对于这种问题,Commons Copress提供了解决方案!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/327878.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

总结尚硅谷的视频springboot视频

这16个章节也就讲个大概&#xff0c;更多内容需要你自己去学习。 第1章尚硅谷SpringBoot入门 P01、尚硅谷_SpringBoot_入门-课程简介 P02、尚硅谷_SpringBoot_入门-Spring Boot简介 P03、尚硅谷_SpringBoot_入门-微服务简介 P04、尚硅谷_SpringBoot_入门-环境准备 P05、尚硅谷_…

微软加入Linux基金会共建开源生态,并对谷歌加入.NET社区的举措表示欢迎

纽约 — 2016年11月16日 — 在周三的年度性Connect();开发者大会上&#xff0c;微软公司公布了一系列产品与合作&#xff0c;以此为基础帮助开发者打造智能的跨平台应用和服务&#xff0c;进而强化微软在Azure云平台方面的优势。微软全球执行副总裁兼云计算与企业事业部负责人 …

mybatis配置mysql连接数_springBoot配置mybatis链接数据库

springBoot配置mybatis链接数据库添加pom包,修改 pom.xml 文件org.mybatis.generatormybatis-generator-core1.3.5org.mybatis.spring.bootmybatis-spring-boot-starter1.3.2mysqlmysql-connector-java修改配置文件application.yml#启动端口server:port: 8001spring:#配置数据源…

Java压缩技术(三) ZIP解压缩——Java原生实现

转载自 Java压缩技术&#xff08;三&#xff09; ZIP解压缩——Java原生实现 解压缩与压缩运作方式相反&#xff0c;原理大抵相同&#xff0c;由ZipInputStream通过read方法对数据解压&#xff0c;同时需要通过CheckedInputStream设置冗余校验码&#xff0c;如&#xff1a; J…

19年8月 字母哥 第二章 RESTFul接口实现与测试 看到这里了

第二章 RESTFul接口实现与测试 2.1.RESTFul接口与http协议状态表述 2.2.常用注解开发一个RESTFul接口 2.2看完了 2.3 JSON数据处理与PostMan测试 树哪里是可以加上去的 list<treeNode> listTreeNode; 为空就不显示了 20%是常用的 80%是不常用的 我只是讲解了20…

java实现验证码3秒刷新一次

<?xml version"1.0" encoding"UTF-8"?> <web-app xmlns"http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://xmlns.jcp.org/xml/ns/javaeehttp://x…

Hibernate中使用Criteria查询及注解——(Dept.hbm.xml)

Dept.hbm.xml 部门表的映射文件: <?xml version"1.0" encoding"utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd&qu…

CentOS上安装SQL Server vNext CTP1

今天微软正式发布上SQL Server 2016 SP1,根据以往的SP1定律&#xff0c;可以在生产环境上使用了。打了SP1的标准版将具有企业版几乎所有的的功能。只有RAM 超过128GB或者超过24核心或者超过4路的环境才必须要安装企业版。 还有一个重要的发布&#xff1a;SQL Server vNext on L…

python弹出窗口 闪烁_Python。得到闪烁/闪烁的窗口

首先&#xff0c;大多数程序通过调用^{}(或包装它的高级函数)来刷新窗口。但是&#xff0c;有一些应用程序主要来自微软&#xff0c;他们做一些定制的东西&#xff0c;在终端用户看来就像是在闪窗&#xff0c;但在封面下看起来可能不一样。希望你不在乎任何这样的定制应用。在无…

Java压缩技术(七) TAR——Commons实现

转载自 Java压缩技术&#xff08;七&#xff09; TAR——Commons实现 顺便复习一遍linux命令&#xff1a; tar cf <file.tar> <file>将由文件<file>创建名为<file.tar>归档文件&#xff0c;同时保留原文件。 tar xf <file.tar>将由归档文件<…

[干货来袭]MSSQL Server on Linux预览版安装教程(先帮大家踩坑)

前言 昨天晚上微软爸爸开了全国开发者大会,会上的内容,我就不多说了,园子里面很多.. 我们唐总裁在今年曾今透漏过SQL Server love Linux,果不其然,这次开发者大会上就推出了MSSQL Server on Linux预览版 官方地址:https://docs.microsoft.com/zh-cn/sql/linux/ E文好的可以自己…

MVC三层架构理解

MVC三层架构 什么是MVC&#xff1a; Model view Controller 模型、视图、控制器 以前的架构 用户直接访问控制层&#xff0c;控制层就可以直接操作数据库&#xff1b; servlet--CRUD-->数据库 弊端&#xff1a;程序十分臃肿&#xff0c;不利于维护 servlet的代码中&…

spring boot建立项目 git推送giteee

gitee上创建项目时候不要创建readme.md 创建完全空的项目 不然上次会报错的 $ git init 初始化git $ git status $ git add . $ git status $ git commit -am 初次建立项目 $ git remote add origin https://gitee.com/yjb1091947832/yangjiabin.git…

vba mysql update多字段_vba操作Mysql使用UPDATE一次更新多组数据

网上查到综合后确定的update语法范例&#xff1a;UPDATE mytable SET myfield CASE WHEN 1 THEN ‘value‘ WHEN 2 THEN ‘value‘ WHEN 3 THEN ‘value‘ END WHERE id IN (1,2,3)下面是我写的一个通用的update库表内容过程&#xff1a;kku为库表&#xff0c;zd为字段&#x…

Hibernate中使用Criteria查询及注解——(hibernate.cfg.xml)

hibernate.cfg.xml hibernate主配置文件&#xff1a; <?xml version1.0 encodingUTF-8?> <!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration…

为什么我不选阿里云(一)

我是资深阿里黑&#xff0c;“资深”体现在我黑阿里和阿里云从来有理有据&#xff0c;我不是小白用户&#xff0c;我本身就是云架构师&#xff0c;我目前主要推荐中国客户上Azure和AWS。 阿里巴巴&#xff08;BABA&#xff09;是一家怎样的公司 阿里巴巴在中国看上去很高大上&a…

Java压缩技术(六) BZIP2——Commons实现

转载自 Java压缩技术&#xff08;六&#xff09; BZIP2——Commons实现 BZip2与GZip有什么渊源&#xff0c;我这里不深究。我要说的只是&#xff0c;这两种算法&#xff0c;你在linux下都可以找到相应的操作命令。GZip 压缩 gzip <file> 将得到压缩文件<file>.gz&…

微信支付师兄

https://www.jianshu.com/writer#/notebooks/41472123/notes/57967685

vpn mysql_MYSQL数据库

1.关系型数据库相关概念关系Relational &#xff1a;关系就是二维表&#xff0c;其中&#xff1a;表中的行、列次序并不重要行row&#xff1a;表中的每一行&#xff0c;又称为一条记录record列column&#xff1a;表中的每一列&#xff0c;称为属性&#xff0c;字段&#xff0c;…

Stateless 3.0——.NET Core上的状态机库

Stateless是一个基于C#&#xff0c;创建状态机的简单库&#xff0c;最新版本支持.NET Core 1.0。其实现方式并不是通过.NET Core&#xff0c;而是通过写入.NET Standard实现的。就像Android平台上API级别抽象出许多底层版本的Android&#xff0c;.NET Standard是一组所有.NET平…