最近复习到IO,想找个案例做一做,恰好下载了许多图片压缩包,查看图片很不方便,所以打算用IO把图片都解压到同一个文件夹下。然后集中打包。

本例使用jdk自带的ZipInputStream和ZipOutPutStream,功能有限不支持rar但是api很简单。

import java.io.*;
import java.util.zip.*; /**
* Created by tm on 2017/2/18.
* time : 17:33
* project_name : toolSite
* 提供zip文件和文件夹的解压和压缩功能。
*/
public class ZipTool { /**
* 压缩单个文件
* 此处传参都是绝对路径。
* @param src 源文件绝对路径名
* @param destPath 将生成的压缩包绝对路径(路径以/结尾)
* @param destName 将生成的压缩包文件名
* @throws IOException
*/
public static void compressFile(String src, String destPath,String destName) throws IOException {
File f = new File(src);
if (!f.exists()) {
throw new RuntimeException("file not find ");
} File folder = new File(destPath);
if(!folder.exists()){
folder.mkdir();
} InputStream is = new FileInputStream(f);
BufferedInputStream buffIn = new BufferedInputStream(is);
//创建文件File,创建文件输出流,包装到Zip文件输出处理流上,最后把Zip处理流再包装到Buffer缓冲输出流中。
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(destPath+destName)));
BufferedOutputStream buffOut = new BufferedOutputStream(zos);
//需要将文件项put到entry中,解压文件时从此entry中获取数据。
zos.putNextEntry(new ZipEntry(f.getName())); //b是指the next byte of data
int b;
while ((b = buffIn.read()) != -1) {
buffOut.write(b);
} buffIn.close();
buffOut.flush();
buffOut.close();
} /**
* 解压单个zip文件(上面压缩后的解压,认为不包含子文件夹)
* @param src 源zip的绝对路径
* @param dest 解压的目标文件夹(路径以/结尾)
* @throws IOException
*/
public static void unCompress(String src, String dest) throws IOException {
File file = new File(src);
if(!file.exists()){
throw new RuntimeException("zip file not found");
} File d = new File(dest);
if(!d.exists()){
d.mkdir();
} InputStream is = new FileInputStream(file);
ZipInputStream zis = new ZipInputStream(is);
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
//解压文件需要从zip中读取每一个entry,一个一个地outPut出来
OutputStream out = new FileOutputStream(new File(dest + entry.getName()));
BufferedOutputStream bos = new BufferedOutputStream(out);
BufferedInputStream buffIn = new BufferedInputStream(new ZipFile(file).getInputStream(entry));
int b;
while ((b = buffIn.read()) != -1) {
bos.write(b);
}
bos.flush();
buffIn.close();
bos.close();
}
zis.close();
} /**
* 压缩指定的文件夹(代码里没有对路径做校验,读者可自行添加,参考上例)
* @param srcFolder 源文件夹
* @param destFileName 目标文件名
* @throws IOException
*/
public static void compressNestFolder(String srcFolder, String destFileName) throws IOException {
System.out.println(">>>>>>>>>>开始压缩");
File folder = new File(srcFolder);
if (!folder.exists()) {
throw new RuntimeException("folder not find Exception");
}
OutputStream os = new FileOutputStream(new File(destFileName));
ZipOutputStream zos = new ZipOutputStream(os);
BufferedOutputStream bo = new BufferedOutputStream(zos);
zipFileOrFolder(zos, bo, "", folder);
zos.close();
bo.close();
System.out.println("压缩完成>>>>>>>>>>");
} /**
* 将目录下所有的文件和子文件都压缩到zos中
* @param zos
* @param bo
* @param src
* @param f
* @throws IOException
*/
private static void zipFileOrFolder(ZipOutputStream zos, BufferedOutputStream bo, String src, File f) throws IOException {
File[] files;
if (f.isDirectory()) {
files = f.listFiles();
assert files != null;
System.out.println("========== " + f.getName());
//添加文件夹的entry,不添加的话,解压时会出问题。
zos.putNextEntry(new ZipEntry(
src+f.getName()+"/"
));
System.out.println(
src+f.getName()+"/"
);
src = src+f.getName() + "/";
for (File f1 : files) {
//使用了递归调用获取下一层文件夹并压缩
zipFileOrFolder(zos, bo, src, f1);
}
} else {
System.out.println("---------- " + f.getName());
InputStream in = new FileInputStream(f);
BufferedInputStream bi = new BufferedInputStream(in);
zos.putNextEntry(new ZipEntry(
src+f.getName()
));
int b;
while ((b = bi.read()) != -1) {
bo.write(b);
}
bo.flush();
bi.close();
zos.closeEntry();
}
} /**
* 解压单个zip文件,保留文件夹层级关系
* @param zipFile
* @param outPath
* @throws IOException
*/
public static void unZip(String zipFile, String outPath) throws IOException {
File zip = new File(zipFile);
ZipFile zf = new ZipFile(zip);
InputStream is = new FileInputStream(zipFile);
ZipInputStream zis = new ZipInputStream(is);
ZipEntry e;
File out = new File(outPath);
if (!out.exists()) {
out.mkdir();
}
while ((e = zis.getNextEntry()) != null) {
System.out.println(e.isDirectory());
File f = new File(outPath + e.getName());
System.out.println(f.getAbsolutePath());
if(e.isDirectory()){
f.mkdir();continue;
}
OutputStream os = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(os);
BufferedInputStream bis = new BufferedInputStream(zf.getInputStream(e));
int b;
while ((b = bis.read()) != -1) {
bos.write(b);
}
bos.flush();
bos.close();
bis.close();
}
zis.close();
} public static void unZipAll(String zipFolder,String destFolder){
//todo
} public static void main(String[] args) throws IOException {
compressFile("D:/test/123.txt", "D:/test/a/b/", "123.zip");
unCompress("D:/test/123.zip", "D:/test/");
compressNestFolder("D:/test/测试zip/新垣结衣/", "D:/test/测试zip/新垣结衣1.zip");
unZip("D:/test/测试zip/新垣结衣1.zip", "D:/test/测试zip/");
}
}

后记:

1.添加到zip中使用putNextEntry,从zip中读取时需要创建一个ZipFile然后从entry中获取InputStream。

2.需要特别注意压缩文件时的Entry存放次序,在添加entry时务必先添加文件夹的entry。因为取entry时,如果乱序就会找不到文件。比如获取/bt/123.pic时,因为没有实现创建父目录/bt,导致写文件时找不到文件。

3.对entry.isDirectory()的判断,api中是根据name是否以 / 结尾的。因此存放folder时,也要使用 / 作为路径分割符。java在windows平台上是支持 / 的,虽然windows平台上路径分隔符是 \  (java中是\\)。建议还是用 / 吧。

4.Zip对象存放文件是使用相对路径的,所以压缩什么的不要有盘符。添加目录时以 / 结尾,多级目录时添加文件使用完全相对路径名 /相对路径1/相对路径2/文件名,可以通过查看打印信息了解方法执行过程。

-----------------以上-----------------

java 压缩与解压的更多相关文章

  1. java压缩文件解压:调用WinRAR5命令强于自己写代码实现

    最近,手上维护着一个几年前的系统,技术是用的JSP+Strust2,系统提供了rar和zip两种压缩格式的解压功能,后台是用java实现的 1.解压rar格式,采用的是java-unrar-0.3.j ...

  2. java压缩与解压

    一 概述 1.目录进入点 目录进入点是文件在压缩文件中的映射,代表压缩文件.压缩文件时,创建目录进入点,将文件写入该目录进入点.解压时,获取目录进入点,将该目录进入点的内容写入硬盘指定文件. 如果目录 ...

  3. java 压缩以及解压文件,有tar,zip,gz(gizp)和解压

    package com.yabsz.decompCompr; import java.io.File; import java.util.ArrayList; import java.util.Lis ...

  4. java压缩与解压文件

    import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import ...

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

    Java实现ZIP的解压与压缩功能基本都是使用了Java的多肽和递归技术,可以对单个文件和任意级联文件夹进行压缩和解压,对于一些初学者来说是个很不错的实例.(转载自http://www.puiedu. ...

  6. Java实现文件压缩与解压[zip格式,gzip格式]

    Java实现ZIP的解压与压缩功能基本都是使用了Java的多肽和递归技术,可以对单个文件和任意级联文件夹进行压缩和解压,对于一些初学者来说是个很不错的实例. zip扮演着归档和压缩两个角色:gzip并 ...

  7. java zip 压缩与解压

    java zip 压缩与解压 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java. ...

  8. PAT(B) 1078 字符串压缩与解压(Java)

    题目链接:1078 字符串压缩与解压 (20 point(s)) 题目描述 文本压缩有很多种方法,这里我们只考虑最简单的一种:把由相同字符组成的一个连续的片段用这个字符和片段中含有这个字符的个数来表示 ...

  9. Java的压缩、解压及压缩加密、解密解压 样例

    为了节约带宽.加快传送速度,http协议支持gzip的压缩,但假设我们的app与后台不是通过http协议通讯的.那么压缩.解压这个流程须要自己写.以下给出compress和decompress的代码: ...

随机推荐

  1. springboot学习笔记-3 整合redis&mongodb

    一.整合redis 1.1 建立实体类 @Entity @Table(name="user") public class User implements Serializable ...

  2. BZOJ 3173 最长上升子序列(树状数组+二分+线段树)

    给定一个序列,初始为空.现在我们将1到N的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字,我们都想知道此时最长上升子序列长度是多少? 由于序列是顺序插入的,所以当前插入的数字对之 ...

  3. Java变量初始化之后的默认值问题

    1) 局部变量初始化(局部变量:函数.语句中的变量,只在所属区域内有效)局部变量声明后,Java虚拟机不会自动给它初始化为默认值.因此对于局部变量,必须经过显示的初始化,才能使用它.如果使用一个没有被 ...

  4. Candies CodeForces - 991C(二分水题)

    就是二分暴力就好了 为什么要记下来 呵呵....emm你说为什么... 行吧 好吧 我一直以为我的二分出问题了 原来不是 依旧很帅 统计的时候求的减了多少次  然后用次数乘了mid 这样做会使那个人获 ...

  5. Intelligent Factorial Factorization LightOJ - 1035(水题)

    就是暴力嘛...很水的一个题... 不好意思交都... #include <iostream> #include <cstdio> #include <sstream&g ...

  6. GIT 旧库迁移到新库

    1.在gitlab创建新项目,得到SSH地址2.用gitextent打开旧项目,记得所有分支合并成一个(如果确实无法合并,则需要一个个复位推送)3.复位到需要推送的节点分支4.打开菜单栏的档案库,管理 ...

  7. Raven: 2靶机入侵

    0x00 前言 Raven 2是一个中等难度的boot2root 虚拟靶机.有四个flag需要找出.在多次被攻破后,Raven Security采取了额外措施来增强他们的网络服务器安全以防止黑客入侵. ...

  8. debian7编译安装tengine添加lua和ldap模块

    1.安装开发环境 # aptitute update # aptitude install -y build-essential # aptitude install -y libldap2-dev ...

  9. 解题:CQOI 2017 老C的任务

    题面 找到真正的KD-Tree题目了!然而出题人并不打算放KD-Tree过,只能O2了 // luogu-judger-enable-o2 #include<cstdio> #includ ...

  10. 【整体二分】【P3527】 [POI2011]MET-Meteors

    Description 有 n 个国家,总共占有一个环,环被分成了 m 段,已知有 k 次流星雨会落在这个环上的一些位置.再给出每个国家目标收集多少流星,对每个国家求出第几次流星雨后可以满足这个国家的 ...