1.ZipInputStream是一种FilterInputStream

  • 可以直接读取zip的内容
  • InputStream->FilterInputStream->InflateInputStream->ZipInputStream->JarInputStream
  • JarInputStream使用ZipInputStream派生出来的,可以直接读取jar文件的MANIFEST.MF文件

ZipInputStream的基本用法:

try(ZipInputStream zip = new ZipInputStream()...){
ZipEntry entry = null;
while((entry=zip.getNextEntry())!=null){//getNextEntry返回null,zip流结束
String name = entry.getName();//每一个entry都表示一个压缩文件或者目录
if(!entry.isDirectory()){
int n;
while((n=zip.read()) != -1){...}//如果entry是压缩文件,就不断读取,直到返回-1
}
}
}

问题:为什么read()传入的zip,不是entry?zip流是按照单个文件读取的。Entry代表当前文件或目录,zip.read()读取返回-1,当前entry结束,开始下一个entry。

2.ZipOutputStream是一种FilterOutputStream

  • 可以直接写入Zip的内容
try(ZipOutputStream zip = new ZipOutputStream(...)){
File[] files = ...
for(File file:files){
zip.putNextEntry(new ZipEntry(file.getName()));//未考虑文件目录的层次结构;如果考虑层次结构,传入的name需要使用相对路径
zip.write(getFilterDataAsBytes(file));//写入byte数据
zip.closeEntry();//结束这个文件的打包
}
}
## 3.示例
```#java
public class Main { public static void main(String[] args) throws IOException {
try(//需要调用ZipInputStream的getNextEntry(),因此没有将zip转型为InputStream
ZipInputStream zip = new ZipInputStream(
new BufferedInputStream(
new FileInputStream("./src/main/java/com/testList/agent.jar")))){
ZipEntry entry = null;
while((entry=zip.getNextEntry())!=null){
if(entry.isDirectory()){
System.out.println("D "+entry.getName()+"\t"+entry.getSize()); }else{
System.out.println("F "+entry.getName()+"\t"+entry.getSize());//打印entry的大小
printFileContent(zip);
}
}
}
}
static void printFileContent(ZipInputStream zip) throws IOException{
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int n = 0;
while((n=zip.read(buffer))!=-1){
output.write(buffer,0,n);
}
byte[] data = output.toByteArray();
System.out.println(" size:"+data.length);
}
}

4.总结:

  • ZipInputStream可以读取Zip格式的流
  • ZipOutputStream可以把数据写入Zip
  • ZipInputStream/ZipOutputStream都是FilterInputStream/FilterOutputStream
  • 配合FileInputStream和File OutputStream就可以读写Zip文件

廖雪峰Java6 IO编程-2input和output-5操作zip的更多相关文章

  1. 廖雪峰Java6 IO编程-2input和output-4Filter模式

    1.JDK提供的InputStream分为两类: 直接提供数据的InputStream * FileInputStream:从文件读取 * ServletInputStream:从HTTP请求读取数据 ...

  2. 廖雪峰Java6 IO编程-2input和output-7序列化

    1.序列化 序列化是指把一个Java对象变成二进制内容byte[] 序列化后可以把byte[]保存到文件中 序列化后可以把byte[]通过网络传输 一个Java对象要能序列化,必须实现Serializ ...

  3. 廖雪峰Java6 IO编程-2input和output-6classpath资源

    1.从classpath读取文件可以避免不同环境下文件路径不一致的问题. Windows和Linux关于路径的表示不一致 Windows:C:\conf\default.properties Linu ...

  4. 廖雪峰Java6 IO编程-3Reader和Writer-2Writer

    1.java.io.Writer和java.io.OutputStream的区别 OutputStream Writer 字节流,以byte为单位 字符流,以char为单位 写入字节(0-255):v ...

  5. 廖雪峰Java6 IO编程-3Reader和Writer-1Reader

    1.java.io.Reader和java.io.InputStream的区别 InputStream Reader 字节流,以byte为单位 字符流,以char为单位 读取字节(-1,0-255): ...

  6. 廖雪峰Java13网络编程-1Socket编程-2TCP编程

    1. Socket 在开发网络应用程序的时候,会遇到Socket这个概念. Socket是一个抽象概念,一个应用程序通过一个Socket来建立一个远程连接,而Socket内部通过TCP/IP协议把数据 ...

  7. 廖雪峰Java13网络编程-3其他-1HTTP编程

    1.HTTP协议: Hyper Text Transfer Protocol:超文本传输协议 基于TCP协议之上的请求/响应协议 目前使用最广泛的高级协议 * 使用浏览器浏览网页和服务器交互使用的就是 ...

  8. 廖雪峰Java13网络编程-1Socket编程-5UDP编程

    1. UDP编程: 不需要建立连接 可以直接发送和接收数据 1.1 客户端 DatagramSocket sock = new DatagramSocket(){} sock.connect(addr ...

  9. 廖雪峰Java13网络编程-1Socket编程-3TCP多线程编程

    TCP多线程编程 一个ServerSocket可以和多个客户端同时建立连接,所以一个Server可以同时与多个客户端建立好的Socket进行双向通信. 因此服务器端,当我们打开一个Socket以后,通 ...

随机推荐

  1. php基础-7

    php json数据的读取和转换 将数组转化为json <?php $arr = array('h'=>"hello", "w"=>" ...

  2. django的url分配和url捕获参数

    django的url分配 一般视图模块(views.py)都放在自己所属的app目录下,在app目录下新建路径模块(urls.py),由app目录下的urls.py来分配当前app的路径. 在app目 ...

  3. mongodb启动很慢

    故障现象mongodb重启后,等了几十分钟还一直没启动完成,单节点副本集,状态一直处于startup 原因分析查看mongod的错误日志,发现一直处于building index,但根据之前的经验,只 ...

  4. LVS简介及使用

    一.LVS是什么? LVS的英文全称是Linux Virtual Server,即Linux虚拟服务器.它是我们国家的章文嵩博士的一个开源项目.在linux内存2.6中,它已经成为内核的一部分,在此之 ...

  5. 重拾C++第一天_WDS

    1.面向对象编程的三大特点:封装.继承.多态 2.C++中若不指定类中成员的访问权限默认就是private的(class默认是private的,struct默认是public的). 3.C++规范中类 ...

  6. 自制操作系统Antz -- 系列文章

    自制操作系统Antz day10——实现shell(上) AntzUhl 2018-10-10 16:25 阅读:192 评论:0   Linux内核源码分析 day01——内存寻址 AntzUhl ...

  7. IDEA 创建maven项目

    说明 创建Maven项目的方式:手工创建 好处:参考IntelliJ IDEA 14 创建maven项目二(此文章描述了用此方式创建Maven项目的好处)及idea14使用maven创建web工程(此 ...

  8. 用windbg 检查内存泄漏

    1.下载编译https://github.com/0cch/luadbg 2.编写脚本1.txt .load luadbg_v15*.sympath+ srv*c:\MyServerSymbols*h ...

  9. Java集合整理

    0,基础概念 Collection:统计大小.插入或删除数据.清空.是否包含某条数据,等等.而Collection就是对这些常用操作进行提取,只是其很全面.很通用.size(),isEmpty(),c ...

  10. win10系统 安装好composer后 cmd 命令行下输入composer提示不是内部或外部的命令,也不是可执行的程序或批处理文件

    在 windows CMD 下运行composer 出现错误提示: 不是内部或外部命令,也不是可运行的程序或批处理文件,这是因为没有配置 PATH 环境变量. 以 win10 为例,找到此电脑右击选择 ...