在日常生活中,我们会经常遇到或使用压缩文件,压缩文件节省了空间,便利了我们日常文件的传输和使用。在JAVA中,也提供了相应的输入输出流来压缩和解压zip、gzip、jar和RAR这样的文件。
1、ZipOutputStream
ZipOutputStream:“压缩文件输出流”,用于将程序中的压缩流写出到磁盘上。这个类实现了一个用于在压缩文件格式中写入文件的输出流过滤器。包括支持压缩和解压项。
//构造方法
ZipOutputStream(OutputStream out) //创建一个新的压缩输出流。
ZipOutputStream(OutputStream out, Charset charset) //创建一个新的压缩输出流。
//常用方法
void close() //关闭压缩输出流,以及被过滤的流。
void closeEntry() //关闭当前的压缩条目并将流写入下一个条目。
void finish() //完成写的压缩输出流的内容,而不关闭底层流。
void putNextEntry(ZipEntry e) //开始编写一个新的压缩文件条目,并将流定位到输入数据的开始处。
void setComment(String comment) //设置文件注释。
void setLevel(int level) //设置后续deflated项压缩级别。
void setMethod(int method) //设置后续项的默认压缩方法。
void write(byte[] b, int off, int len) //将一个字节数组写入当前的压缩输入数据。
如要从ZIP压缩管理文件内读取某个文件,要先找到对应该文件的“目录进入点”(从它可知该文件在ZIP文件内的位置),才能读取这个文件的内容。如果要将文件内容写入ZIP文件内,必须先写入对应于该文件的“目录进入点”,并且把要写入文件内容的位置移到此进入点所指的位置,然后再写入文件内容。。ZipEntry类产生的对象,是用来代表一个ZIP压缩文件内的进入点(entry)。ZipInputStream类用来读取ZIP压缩格式的文件,所支持的包括已压缩及未压缩的进入点(entry)。ZipOutputStream类用来写出ZIP压缩格式的文件,而且所支持的包括已压缩及未压缩的进入点(entry)。
压缩的过程:
(1)打开输出ZIP文件;
(2)添加一个ZipEntry;
(3)打开一个输入文本,读数据,向ZipEntry写数据,关闭输入文本;
(4)重复(2)、(3)步骤,可以写入多个文件到ZIP文件中;
(5)关闭zip文件。
以下实例是压缩E盘的dir1/dir文件夹,dir文件夹下要有文件,比如(1.txt文件)。并将压缩后的dir.zip文件夹保存在E盘dir1目录下。下面的代码要好好理解。
import java.io.File ;
import java.io.FileInputStream ;
import java.io.InputStream ;
import java.util.zip.ZipEntry ;
import java.util.zip.ZipOutputStream ;
import java.io.FileOutputStream ;
public class MultipleFileZip{
public static void main(String args[]) throws Exception{
File file = new File("e:/dir1/dir") ; // 定义要压缩的文件夹
File zipFile = new File("e:/dir1/dir.zip") ; // 定义压缩文件名称
InputStream input = null ; // 定义文件输入流
ZipOutputStream zipOut = null ; // 声明压缩流对象
zipOut = new ZipOutputStream(new FileOutputStream(zipFile)) ;
//zipOut.setComment("multiple file zip") ; // 设置注释
//开始压缩
int temp = 0 ;
if(file.isDirectory())// 判断是否是文件夹
{
File lists[] = file.listFiles() ; // 列出全部子文件
for(int i=0;i<lists.length;i++)
{
System.out.println("子文件: "+lists[i]);
}
for(int i=0;i<lists.length;i++)
{
input = new FileInputStream(lists[i]) ; //定义文件的输入流
//注意压缩的文件夹中最好不要带上“E:/”“C:/”等盘号,否则解压是会出错,无法解压
//上面所得到的lists[i]中,可以看到带有盘号,所以要处理一下。
zipOut.putNextEntry(new ZipEntry(file.getName()+File.separator+lists[i].getName())) ; //设置ZipEntry对象
System.out.println("正在压缩:" + lists[i].getName());
while((temp=input.read())!=-1)//读取内容
{
zipOut.write(temp) ; // 压缩输出
}
input.close() ;
}
}
zipOut.close() ;
System.out.println("multiple file zip done.");
}
}
2、ZipInputStream
ZipInputStream :“压缩文件输入流”,用于读取磁盘上的压缩文件。这个类实现了一个用于读取压缩文件格式中的文件的输入流过滤器。包括支持压缩和解压项。
ZipInputStream类可读取ZIP压缩格式的文件,包括已压缩和未压缩的条目(entry)。
//构造函数
ZipInputStream(InputStream in) //创建一个新的压缩输入流。
ZipInputStream(InputStream in, Charset charset) //创建一个新的压缩输入流。
//常用方法
int available() //在当前条目数据的EOF达到后返回0,否则始终返回1。
void close() //关闭此输入流并释放与流关联的任何系统资源。
void closeEntry() //关闭当前的压缩条目并将流用于读取下一个条目。
protected ZipEntry createZipEntry(String name) //创建指定条目名称的新 ZipEntry对象。
ZipEntry getNextEntry() //读取下一个压缩文件条目,并在输入数据的开头处的流中的位置。
int read(byte[] b, int off, int len) //从当前的压缩条目读入一个字节数组。
long skip(long n) //跳过当前ZIP项的指定字节数。
解压过程:
(1)打开输入的zip文件;
(2)获取下一个ZipEntry;
(3)新建一个目标文件,从zipEntry读取数据,向目标文件写入数据;
(4)重复(2)(3)步骤,从zip文件中读取数据到多个目标文件;
(5)关闭zip文件。
以下实例是将上面压缩的文件解压;过程要好好理解。
import java.io.File ;
import java.io.FileInputStream ;
import java.io.FileOutputStream ;
import java.io.InputStream ;
import java.io.OutputStream ;
import java.util.zip.ZipEntry ;
import java.util.zip.ZipFile ;
import java.util.zip.ZipInputStream ;
public class MultipleFileUnzip{
public static void main(String args[]) throws Exception{
//待解压的zip文件,需要在zip文件上构建输入流,读取数据到Java中
File file = new File("E:/dir1/dir.zip") ; // 定义压缩文件名称
File outFile = null ; // 输出文件的时候要有文件夹的操作
ZipFile zipFile = new ZipFile(file) ; // 实例化ZipFile对象
ZipInputStream zipInput = null ; //定义压缩输入流
//定义解压的文件名
OutputStream out = null ; // 定义输出流,用于输出每一个实体内容
InputStream input = null ; //定义输入流,读取每一个ZipEntry
ZipEntry entry = null ; // 每一个压缩实体
zipInput = new ZipInputStream(new FileInputStream(file)) ; // 实例化ZipInputStream
//遍历压缩包中的文件
while((entry = zipInput.getNextEntry())!=null){ //得到一个压缩实体
System.out.println("正在解压" + entry.getName()) ;
outFile = new File("E:/dir/" + entry.getName()) ; // 定义输出的文件路径
if(!outFile.getParentFile().exists())// 如果输出文件夹不存在
{
outFile.getParentFile().mkdirs() ; //创建文件夹
}
if(!outFile.exists()){ // 判断输出文件是否存在
if(entry.isDirectory())
{
outFile.mkdirs();
}
else
{
outFile.createNewFile() ; // 创建文件
}
}
if(!entry.isDirectory())
{
input = zipFile.getInputStream(entry) ; // 得到每一个实体的输入流
out = new FileOutputStream(outFile) ; // 实例化文件输出流
int temp = 0 ;
while((temp=input.read())!=-1){
out.write(temp) ;
}
input.close() ;
out.close() ;
}
}
input.close() ;
}
}