最近在一个项目中需要对文件进行自动的解压缩,Java提供了这种支持,还是挺好用的。

工具包封装在java.util.zip中。

1.首先是多个文件压缩成一个ZIP文件

思路:用一个ZipOutputStream包装一个目的ZIP文件--->遍历文件数组:对每一个文件创建一个ZipEntry并put进ZipOutputStream中。读取当前文件的数据流写入ZipOutputStream中。

代码实现:

  1. import java.io.BufferedInputStream;
  2. import java.io.BufferedOutputStream;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileNotFoundException;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.util.zip.ZipEntry;
  9. import java.util.zip.ZipOutputStream;
  10.  
  11. /**
  12. *多文件压缩
  13. *@author wxisme
  14. *@time 2015-9-24 下午5:13:32
  15. */
  16.  
  17. public final class FilesToZip {
  18.  
  19. private FilesToZip(){}
  20.  
  21. /**
  22. * 压缩多个文件到一个zip文件中
  23. * @param files 待压缩文件数组
  24. * @param zipFilePath 压缩后的zip文件路径
  25. * @param fileName zip文件的名字
  26. * @return 是否成功
  27. */
  28. public static boolean fileToZip(File[] files,String zipFilePath,String fileName){
  29. boolean flag = false;
  30. FileInputStream fis = null;
  31. BufferedInputStream bis = null;
  32. FileOutputStream fos = null;
  33. ZipOutputStream zos = null;
  34.  
  35. try {
  36. File zipFile = new File(zipFilePath + "/" + fileName +".zip");
  37. if(zipFile.exists()) {
  38. zipFile.delete();
  39. }
  40. File[] sourceFiles = files;
  41. fos = new FileOutputStream(zipFile);
  42. zos = new ZipOutputStream(new BufferedOutputStream(fos));
  43. byte[] bufs = new byte[1024*10];
  44. for(int i=0;i<sourceFiles.length;i++){
  45. //创建ZIP实体,并添加进压缩包
  46. ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
  47. zos.putNextEntry(zipEntry);
  48. //读取待压缩的文件并写进压缩包里
  49. fis = new FileInputStream(sourceFiles[i]);
  50. bis = new BufferedInputStream(fis, 1024*10);
  51. int read = 0;
  52. while((read=bis.read(bufs, 0, 1024*10)) != -1){
  53. zos.write(bufs,0,read);
  54. }
  55. }
  56. flag = true;
  57.  
  58. } catch (FileNotFoundException e) {
  59. e.printStackTrace();
  60. throw new RuntimeException(e);
  61. } catch (IOException e) {
  62. e.printStackTrace();
  63. throw new RuntimeException(e);
  64. } finally{
  65. //关闭流
  66. try {
  67. if(null != bis) bis.close();
  68. if(null != zos) zos.close();
  69. } catch (IOException e) {
  70. e.printStackTrace();
  71. throw new RuntimeException(e);
  72. }
  73. }
  74.  
  75. return flag;
  76. }
  77.  
  78. }

2.对包含有文件夹的文件数组进行压缩

思路:遍历文件数组,判断是否是文件。如果是文件步骤同1,如果是文件夹(目录)则递归压缩这个文件夹。其他步骤和1类似。

代码实现:

  1. import java.io.File;
  2. import java.io.FileInputStream;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.util.zip.ZipEntry;
  6. import java.util.zip.ZipOutputStream;
  7.  
  8. /**
  9. *多文件夹压缩
  10. *@author wxisme
  11. *@time 2015-9-24 下午7:36:06
  12. */
  13. public final class MultiZip {
  14.  
  15. public static void ZipFiles(ZipOutputStream out,String path,File... srcFiles) {
  16. path = path.replaceAll("\\*", "/");
  17. if(!path.endsWith("/")){
  18. path+="/";
  19. }
  20. byte[] buf = new byte[1024];
  21. try {
  22. for(int i=0;i<srcFiles.length;i++){
  23. if(srcFiles[i].getName().endsWith(".zip")) {
  24. //防止形成死循环
  25. continue;
  26. }
  27. if(srcFiles[i].isDirectory()){
  28. File[] files = srcFiles[i].listFiles();
  29. String srcPath = srcFiles[i].getName();
  30. srcPath = srcPath.replaceAll("\\*", "/");
  31. if(!srcPath.endsWith("/")){
  32. srcPath+="/";
  33. }
  34. out.putNextEntry(new ZipEntry(path+srcPath));
  35. ZipFiles(out,path+srcPath,files);
  36. }
  37. else{
  38. FileInputStream in = new FileInputStream(srcFiles[i]);
  39. System.out.println(path + srcFiles[i].getName());
  40. out.putNextEntry(new ZipEntry(path + srcFiles[i].getName()));
  41. int len;
  42. while((len=in.read(buf))>0){
  43. out.write(buf,0,len);
  44. }
  45. out.closeEntry();
  46. in.close();
  47. }
  48. }
  49. } catch (Exception e) {
  50. e.printStackTrace();
  51. }
  52. }
  53.  
  54. public static void ZipFiles(File zip,String path,File... srcFiles) throws IOException {
  55. if(zip.exists()) {
  56. zip.delete();
  57. }
  58. ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zip));
  59. ZipFiles(out,path,srcFiles);
  60. out.close();
  61. }
  62.  
  63. }

3.解压

思路:获取压缩文件的ZipEntry,对每个ZipEntry进行恢复操作。创建同名文件获取数据流写入文件。

代码实现:

  1. package com.wxisme.demo;
  2.  
  3. import java.io.BufferedInputStream;
  4. import java.io.BufferedOutputStream;
  5. import java.io.File;
  6. import java.io.FileOutputStream;
  7. import java.util.Enumeration;
  8. import java.util.zip.ZipEntry;
  9. import java.util.zip.ZipFile;
  10.  
  11. /**
  12. *解压文件
  13. *@author wxisme
  14. *@time 2015-10-5 下午9:18:57
  15. */
  16. public class Decompression {
  17.  
  18. /**
  19. * 解压
  20. * @param zipFilePath 待解压文件的路径
  21. * @param unzipFilePath 解压后的文件存储路径
  22. * @throws Exception
  23. */
  24. public static void unzip(String zipFilePath, String unzipFilePath) throws Exception {
  25. File zipFile = new File(zipFilePath);
  26.  
  27. //创建解压缩文件保存的路径
  28. File unzipFileDir = new File(unzipFilePath);
  29. if (!unzipFileDir.exists() || !unzipFileDir.isDirectory()) {
  30. unzipFileDir.mkdirs();
  31. }
  32.  
  33. //开始解压
  34. ZipEntry entry = null;
  35. String entryFilePath = null, entryDirPath = null;
  36. File entryFile = null, entryDir = null;
  37. int index = 0, count = 0;
  38. byte[] buffer = new byte[1024];
  39. BufferedInputStream bis = null;
  40. BufferedOutputStream bos = null;
  41. ZipFile zip = new ZipFile(zipFile);
  42. Enumeration<ZipEntry> entries = (Enumeration<ZipEntry>)zip.entries();
  43. //循环对压缩包里的每一个文件进行解压
  44. while(entries.hasMoreElements()) {
  45. entry = entries.nextElement();
  46. //构建压缩包中一个文件解压后保存的文件全路径
  47. entryFilePath = unzipFilePath + File.separator + entry.getName();
  48. //构建解压后保存的文件夹路径
  49. index = entryFilePath.lastIndexOf(File.separator);
  50. if (index != -1) {
  51. entryDirPath = entryFilePath.substring(0, index);
  52. }
  53. else {
  54. entryDirPath = "";
  55. }
  56. entryDir = new File(entryDirPath);
  57. //如果文件夹路径不存在,则创建文件夹
  58. if (!entryDir.exists() || !entryDir.isDirectory()) {
  59. entryDir.mkdirs();
  60. }
  61.  
  62. //创建解压文件
  63. entryFile = new File(entryFilePath);
  64. if (entryFile.exists()) {
  65. //检测文件是否允许删除,如果不允许删除,将会抛出SecurityException
  66. SecurityManager securityManager = new SecurityManager();
  67. securityManager.checkDelete(entryFilePath);
  68. //删除已存在的目标文件
  69. entryFile.delete();
  70. }
  71.  
  72. //写入文件
  73. bos = new BufferedOutputStream(new FileOutputStream(entryFile));
  74. bis = new BufferedInputStream(zip.getInputStream(entry));
  75. while ((count = bis.read(buffer, 0, 1024)) != -1) {
  76. bos.write(buffer, 0, count);
  77. }
  78. bos.flush();
  79. bos.close();
  80. }
  81. }
  82.  
  83. }

注意:在压缩文件时,如果压缩路径包含要创建的zip文件就要注意逃过同名的zip文件,否则会造成死循环。

使用Java对文件进行解压缩的更多相关文章

  1. java zip文件的解压缩(支持中文文件名)

    用的apache的ant包,下载导入即可.由于过程比较简单,直接上代码. 代码可直接复制使用. 如果想在android上使用,记得要在AndroidManifest.xml里添加权限: <use ...

  2. java Zip文件解压缩

    java Zip文件解压缩 为了解压缩zip都折腾两天了,查看了许多谷歌.百度来的code, 真实无语了,绝大多数是不能用的.这可能跟我的开发环境有关吧. 我用的是Ubuntu14.04,eclips ...

  3. Java实现压缩文件与解压缩文件

    由于工作需要,需要将zip的压缩文件进行解压,经过调查发现,存在两个开源的工具包,一个是Apache的ant工具包,另一个就是Java api自带的工具包:但是Java自带的工具包存在问题:如果压缩或 ...

  4. Java实现对zip和rar文件的解压缩

    通过java实现对zip和rar文件的解压缩

  5. java代理使用 apache ant实现文件压缩/解压缩

    [背景] 近日在研究web邮件下载功能,下载的邮件能够导入foxmail邮件client.可是批量下载邮件还需将邮件打成一个压缩包. 从网上搜索通过java实现文件压缩.解压缩有非常多现成的样例. [ ...

  6. java创建文件和目录

    java创建文件和目录 2013-09-04 12:56 99933人阅读 评论(7) 收藏 举报  分类: JAVA基础(10)  版权声明:本文为博主原创文章,未经博主允许不得转载. 创建文件和目 ...

  7. java之文件基本操作

    java之文件基本操作 1 使用 BufferedReader 在控制台读取字符 public static void readChar() throws IOException{ char c; I ...

  8. java中文件的I/O操作

    java中文件的读写操作 (一) (1)java中文件的字节转成字符读操作 FileInputStream fStream = new FileInputStream("test.txt&q ...

  9. java进行文件上传,带进度条

    网上看到别人发过的一个java上传的代码,自己写了个完整的,附带源码 项目环境:jkd7.tomcat7. jar包:commons-fileupload-1.2.1.jar.commons-io-1 ...

随机推荐

  1. Android——String.IndexOf 方法 (value, [startIndex], [count])

    报告指定字符在此实例中的第一个匹配项的索引.搜索从指定字符位置开始,并检查指定数量的字符位置.  参数 value  要查找的 Unicode 字符. 对 value 的搜索区分大小写. startI ...

  2. win10系统中UserManager 总是被禁用怎么解决?

    RT,也就是提示win10开始菜单和cortana无法工作.升级win10后一直被这个问题困扰,论坛也见有人发帖求助这类问题,百度了方法打开任务管理器进入服务更改User Manager启动类型为自动 ...

  3. EasyUI的treegrid组件动态加载数据问题的解决办法

    http://www.jquerycn.cn/a_3455 —————————————————————————————————————————————————————————————————————— ...

  4. ajax传值 乱码问题

    ajax.overrideMimeType("text/xml;charset=GBK");

  5. 关于Cocos2d-x中根据分数增加游戏难度的方法

    1.GameScene.h中声明一些分数边界值 //level提升所需的分数 enum LevelUp_Score { Level1Up_Score = , Level2Up_Score = , Le ...

  6. JavaScript 杂乱的小总结

    基本类型只有String.number.boolean.null.undefined,还有一个Object.存在装箱类型,不过后台自动转换. 通过new创建对象时,如果没有参数,可以省略“()”.-- ...

  7. 有一个TIME的类要求输出分和秒的值

    #include <iostream> /* run this program using the console pauser or add your own getch, system ...

  8. 关掉firefox(火狐)和palemoon地址栏自动加www.前缀功能【转】

    常用palemoon调试网站域名,它会很“贴心”的给你输入的网址前加上www.前缀,可有些域名前并没有www前缀,这样就导致了无法打开网站,今天学习下关闭它的这个功能. 打开firefox,在地址栏输 ...

  9. 文本处理三剑客之AWK的用法

    1.awk命令简介: awk是一种可以处理数据.产生格式化报表的语言,功能十分强大. awk的工作方式是读取数据,将每一行数据视为一条记录(record)每笔记录以字段分隔符分成若干字段,然后输出各个 ...

  10. 【Java面试题】45 什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。

    我们有时候将一个java对象变成字节流的形式传出去或者从一个字节流中恢复成一个java对象,例如,要将java对象存储到硬盘或者传送给网络上的其他计算机,这个过程我们可以自己写代码去把一个java对象 ...