勿以恶小而为之,勿以善小而不为--------------------------刘备
劝诸君,多行善事积福报,莫作恶
上一章简单介绍了 合并流SequenceInputStream和回退流PushbackInputStream(十),如果没有看过,请观看上一章
一. 压缩和解压缩
生活中,我们常见的有 .zip(Windows系统), .jar, .gzip(Linux系统) 等压缩包。 Java语言,也可以实现 压缩和解压缩的功能 。
一个压缩包:
data.txt, data2.txt,129.png 都放置在 A.zip 压缩文件下, 它们叫做 ZipEntry,是文件条目。
我们要想压缩文件, 需要用到 ZipOutputStream 类。
压缩的那个文件,如 A.zip ,不能用普通的 File 类进行接收, 而应该用 ZipFile 类。
我们想要解压缩, 那么需要用到 ZipInputStream 类。
所以,压缩和解压缩 需要用到 ZipEntry, ZipOutputStream, ZipFile, ZipInputStream 四个类。
二. 文件条目 ZipEntry
public class ZipEntry implements ZipConstants, Cloneable {
}
父类是 Object.
二.一 方法
二.一.一 构造方法
二.一.一.一 方法
方法 | 作用 |
---|---|
ZipEntry(String name) | 传入文件的名称,唯一值,不能重复 |
ZipEntry(ZipEntry e) | 传入zipEntry 对象,可以进行嵌套, 压缩文件里面还有压缩文件 |
二.一.一.二 演示
public void entryConTest(){
//第一种方式
ZipEntry zipEntry=new ZipEntry("压缩文件.txt");
//第二种方式
ZipEntry zipEntry1=new ZipEntry(zipEntry);
}
一般都采用第一种方式, 直接传入唯一的文件名称。
二.一.二 其他方法
方法 | 作用 |
---|---|
boolean isDirectory() | 判断是否是目录,如果是目录,就返回true,不是目录,返回false |
void setComment(String comment) | 设置注释 |
void setCreationTime(FileTime time) | 设置创建的时间 |
void setSize(long size) | 设置文件的大小 |
void setTime(long time) | 设置最后的修改时间 |
ZipEntry setLastAccessTime(FileTime time) | 设置最后的访问时间 |
ZipEntry setLastModifiedTime(FileTime time) | 设置最后的修改时间 |
String getComment() | 获取注释 |
FileTime getCreationTime() | 获取创建时间 |
FileTime getLastAccessTime() | 获取最后访问时间 |
FileTime getLastModifiedTime() | 获取最后修改时间 |
String getName() | 获取名称 |
long getSize() | 获取大小 |
long getTime() | 获取最后的修改时间 |
单独的 ZipEntry 是无法存在的,需要与其他的对象关联使用。
三. Zip文件压缩输出流 ZipOutputStream
三.一 方法
三.一.一 构造方法
三.一.一.一 方法
方法 | 作用 |
---|---|
ZipOutputStream(OutputStream out) | 传入 输出流 outputStream 对象 |
ZipOutputStream(OutputStream out, Charset charset) | 传入输出流和文件编码 |
三.一.一.二 演示
@Test
public void conTest() throws Exception{
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"jdk91.zip");
ZipOutputStream zipOutputStream=new ZipOutputStream(new FileOutputStream(file));
}
三.一.二 其他方法
方法 | 作用 |
---|---|
void close() | 关闭输出流 |
void setComment(String comment) | 设置文件注释 |
void write(byte[] b, int off, int len) | 写数据到字节数组 |
void putNextEntry(ZipEntry e) | 开始编写新的ZIP文件条目,并将流定位到条目数据的开头。 |
三.二 演示 ZipOutputStream
三.二.一 压缩单个文件
@Test
public void zip1Test() throws Exception{
//找到要压缩的那个文件, 作输入流
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"jdk9.CHM");
InputStream inputStream=new FileInputStream(file);
//定义要压缩到的那个文件为 输出流
File outFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"jdk9.zip");
OutputStream outputStream=new FileOutputStream(outFile);
//定义ZipOutputStream, 传入目标文件的outputStream
ZipOutputStream zipOutputStream=new ZipOutputStream(outputStream);
//放置压缩里面的内容,这样就算是放置进去了。
zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
//设置注释
zipOutputStream.setComment("这是什么玩意 ");
byte[] bytes=new byte[1024];
int len=-1;
//读取文件到字节数组
while((len=inputStream.read(bytes))!=-1){
// 进行压缩,写入字节数组
zipOutputStream.write(bytes,0,len);
}
//关闭
zipOutputStream.close();
outputStream.close();
inputStream.close();
}
压缩前:
运行程序,再次查看文件系统
点进去该文件 jdk9.zip,可以进行查看
注意: 压缩文件时,也可以放置多个文件进去。
zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
zipOutputStream.putNextEntry(new ZipEntry(file1.getName()));
zipOutputStream.putNextEntry(new ZipEntry(fil2.getName()));
zipOutputStream.putNextEntry(new ZipEntry(file3.getName()));
这样 jdk9.zip 里面,就可以有四个文件了。
三.二.二 压缩文件夹
将 data,data2,data3,data4 复制一份到 a 文件夹下。
@Test
public void zip2Test() throws Exception{
//1. 定义压缩输入 的目录
File inFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"a");
InputStream inputStream=null;
//2.定义 压缩输出文件
File outFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"a.zip");
ZipOutputStream zipOutputStream=new ZipOutputStream(new FileOutputStream(outFile));
zipOutputStream.setComment("压缩文件夹");
//如果文件是一个目录的话
if(inFile.isDirectory()){
//查询该目录下的文件
File[] fileList=inFile.listFiles();
for(File f:fileList){
if(f.isDirectory()){
continue;
}
//为每一个文件设置一个 输入流
inputStream=new FileInputStream(f);
//设置压缩文件条目
zipOutputStream.putNextEntry(new ZipEntry(f.getName()));
//
byte[] bytes=new byte[1024];
int len=-1;
while((len=inputStream.read(bytes))!=-1){
// 进行压缩
zipOutputStream.write(bytes,0,len);
}
}
//关闭
zipOutputStream.close();
inputStream.close();
}else{ //是普通文件
inputStream=new FileInputStream(inFile);
zipOutputStream.putNextEntry(new ZipEntry(inFile.getName()));
byte[] bytes=new byte[1024];
int len=-1;
while((len=inputStream.read(bytes))!=-1){
// 进行压缩
zipOutputStream.write(bytes,0,len);
}
//关闭
zipOutputStream.close();
inputStream.close();
}
}
运行程序, 查看文件系统
有一个 a.zip 压缩文件,里面有那四个文件。
四. 压缩文件 ZipFile
public class ZipFile implements ZipConstants, Closeable {
}
四.一 方法
四.一.一 构造方法
四.一.一.一 方法
方法 | 作用 |
---|---|
ZipFile(File file) | 传入压缩文件 |
ZipFile(String name) | 传入压缩文件的名称 |
四.一.一.二 演示
@Test
public void zipFileConTest() throws Exception{
//第一种方式,传入文件
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"a.zip");
ZipFile zipFile=new ZipFile(file);
//第二种方式,传入文件的路径
String path="E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"a.zip";
ZipFile zipFile1=new ZipFile(path);
}
四.一.二 其他方法
方法 | 作用 |
---|---|
int size() | 获取文件的大小 |
String getName() | 获取文件的名称 |
String getComment() | 获取注释 |
ZipEntry getEntry(String name) | 根据名称获取 zipEntry. name是我们原先就要知道的 |
InputStream getInputStream(ZipEntry entry) | 根据 zipEntry 获取 inputStream流 |
Enumeration<? extends ZipEntry> entries() | 获取该压缩文件夹下的 zipEntry 集合 |
四.二 演示压缩文件 ZipFile
四.二.一 获取压缩文件的基本信息
@Test
public void zipFileTest() throws Exception{
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"a.zip");
ZipFile zipFile=new ZipFile(file);
System.out.println("获取文件注释:"+zipFile.getComment());
System.out.println("文件名称:"+zipFile.getName());
System.out.println("文件大小:"+zipFile.size());
//根据名称,获取 zipEntry
ZipEntry zipEntry=zipFile.getEntry("data.txt");
System.out.println("输出名称:"+zipEntry.getName());
//根据 zipEntry 获取 输入流
InputStream inputStream=zipFile.getInputStream(zipEntry);
System.out.println("*************************");
//获取压缩文件下的所有条目
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while(entries.hasMoreElements()){
ZipEntry temp=entries.nextElement();
System.out.println("输出名称:"+temp.getName());
}
}
运行程序, 控制台打印输出:
四.二.二 根据条目文件名称,解压缩单个文件
@Test
public void zipFile1Test() throws Exception{
//1. 先定义好输出流
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"解压缩单个文件.txt");
OutputStream outputStream=new FileOutputStream(file);
//找到压缩文件
File inputFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"a.zip");
ZipFile zipFile=new ZipFile(inputFile);
//根据名称,获取 ZipEntry。 只解压缩 a.zip 中的 data.txt 文件
ZipEntry zipEntry=zipFile.getEntry("data.txt");
//获取输入流
InputStream inputStream=zipFile.getInputStream(zipEntry);
byte[] bytes=new byte[1024];
int len=-1;
//读出
while((len=inputStream.read(bytes))!=-1){
//写入
outputStream.write(bytes,0,len);
}
outputStream.close();
inputStream.close();
}
运行程序,查看文件系统
内容也是有的,与 a.zip 文件下的 data.txt 内容一致。
现在解压缩,我们知道要解压缩的文件名称,然而大部分情况下,是不知道要解压缩的文件名称的。
五. ZipInputStream
解压缩文件的输入流。
五.一 方法
五.一.一 构造方法
五.一.一.一 方法
方法 | 作用 |
---|---|
ZipInputStream(InputStream in) | 传入输入流 |
ZipInputStream(InputStream in, Charset charset) | 传入输入流和字符编码 |
五.一.一.二 举例
@Test
public void zipInputStreamConTest() throws Exception{
//File inputFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
// +File.separator+"jdk91.zip");
File inputFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"a.zip");
InputStream inputStream=new FileInputStream(inputFile);
// 传入输入流
ZipInputStream zipInputStream=new ZipInputStream(inputStream);
}
五.一.二 其他方法
方法 | 作用 |
---|---|
void close() | 关闭此输入流并释放与流相关联的任何系统资源。 |
void closeEntry() | 关闭当前的ZIP条目,并定位流以读取下一个条目。 |
ZipEntry getNextEntry() | 读取下一个ZIP文件条目,并将流定位在条目数据的开头。放置到while中循环判断 |
int read(byte[] b, int off, int len) | 从当前ZIP条目读取到字节数组。 |
protected ZipEntry createZipEntry(String name) | 为指定的条目名称创建一个新的 ZipEntry对象。 |
五.二. 举例 ZipInputStream
五.二.一 解压缩文件
//解压缩文件
@Test
public void zipFile2Test() throws Exception{
//1. 先定义好解压缩的文件
File file=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"c");
//找到压缩文件
File inputFile=new File("E:"+ File.separator+"ideaWork"+File.separator+"Java2"+File.separator+"fileSrc"
+File.separator+"a.zip");
InputStream inputStream=new FileInputStream(inputFile);
//输入流
ZipInputStream zipInputStream=new ZipInputStream(inputStream);
//压缩文件
ZipFile zipFile=new ZipFile(inputFile);
//定义每一个文件
ZipEntry zipEntry=null;
//先看父存不在
if(file.getParent()==null){
file.mkdirs();
}
while((zipEntry=zipInputStream.getNextEntry())!=null){
//说明有子。
String name=zipEntry.getName();
//解压到当前的目录。
File newFile=new File(file,name);
if(!newFile.getParentFile().exists()){
newFile.getParentFile().mkdirs();
}
//创建当前文件
if(!newFile.exists()){
newFile.createNewFile();
}
//获取每一个流,根据 zipEntry
InputStream inputStream1=zipFile.getInputStream(zipEntry);
//替换型
OutputStream newOutputStream=new FileOutputStream(newFile);
byte[] bytes=new byte[1024];
int len=-1;
while((len=inputStream1.read(bytes))!=-1){
//写入
newOutputStream.write(bytes,0,len);
}
newOutputStream.close();
inputStream1.close();
}
System.out.println("文件夹解压缩成功");
zipInputStream.close();
inputStream.close();
}
现在,系统里面没有 c 文件夹。
运行程序,查看文件系统,解压缩成功。
谢谢您的观看,如果喜欢,请关注我,再次感谢 !!!