最近在复习java的IO流,发现zip流这块还是空白,所以补补课,发现一片比较好的文档,所以转载了,出处:http://blog.csdn.net/hanshileiai/article/details/6718375?reload,个人觉得写的比较好,其中的方法我也按照它的思路测试过,没有问题。
?
1、了解压缩流的主要作用
2、了解JAVA IO 支持的三种压缩格式
3、掌握ZipOutputStream、ZipFile、ZipInputStream 三个类的作用
具体内容
经常可以看见各种压缩文件:zip、jar、GZ、
正常情况下在IO 操作中,所有的类库都是在 IO 包中。
在实例化ZipEntry 的时候,要设置名称,此名称实际上就是压缩文件中每一个元素的名称。
1、ZipOutputStream
此类的功能就是完成ZIP格式输出的。
继承关系:
?
java.lang.Object
java.io.OutputStream
java.io.FilterOutputStream
java.util.zip.DeflaterOutputStream
java.util.zip.ZipOutputStream
?
从定义可以发现,就是一个字节的输出流。
?
public void putNextEntry(ZipEntry?e)
throws IOException
在压缩文件中,每一个压缩的内容都可以用一个ZipEntry 表示,所以在进行压缩之前必须通过putNextEntry 设置一个ZipEntry 即可。
?
?
[java]?view plaincopy
?
class="dp-j" style="border: none; background-color: #ffffff; color: #5c5c5c; margin-bottom: 1px !important; margin-left: 45px !important;">
- 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?ZipOutputStreamDemo01{??
- ????public?static?void?main(String?args[])?throws?Exception{??????
- ????????File?file?=?new?File("d:"?+?File.separator?+?"mldn.txt")?;????
- ????????File?zipFile?=?new?File("d:"?+?File.separator?+?"mldn.zip")?;?????
- ????????InputStream?input?=?new?FileInputStream(file)?;???
- ????????ZipOutputStream?zipOut?=?null?;???
- ????????zipOut?=?new?ZipOutputStream(new?FileOutputStream(zipFile))?;??
- ????????zipOut.putNextEntry(new?ZipEntry(file.getName()))?;???
- ????????zipOut.setComment("www.mldnjava.cn")?;????
- ????????int?temp?=?0?;??
- ????????while((temp=input.read())!=-1){???
- ????????????zipOut.write(temp)?;??????
- ????????}??
- ????????input.close()?;???
- ????????zipOut.close()?;??????
- ????}??
- };??
以上的操作代码完成的只是一个文件的压缩,如果要完成一个文件夹呢?
?
[java]?view plaincopy
?
- 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?ZipOutputStreamDemo02{??
- ????public?static?void?main(String?args[])?throws?Exception{??????
- ????????File?file?=?new?File("d:"?+?File.separator?+?"mldn")?;????
- ????????File?zipFile?=?new?File("d:"?+?File.separator?+?"mldndir.zip")?;??????
- ????????InputStream?input?=?null?;????
- ????????ZipOutputStream?zipOut?=?null?;???
- ????????zipOut?=?new?ZipOutputStream(new?FileOutputStream(zipFile))?;??
- ????????zipOut.setComment("www.mldnjava.cn")?;????
- ????????int?temp?=?0?;??
- ????????if(file.isDirectory()){???
- ????????????File?lists[]?=?file.listFiles()?;?????
- ????????????for(int?i=0;i<lists.length;i++){??
- ????????????????input?=?new?FileInputStream(lists[i])?;???
- ????????????????zipOut.putNextEntry(new?ZipEntry(file.getName()??
- ????????????????????+File.separator+lists[i].getName()))?;????
- ????????????????while((temp=input.read())!=-1){???
- ????????????????????zipOut.write(temp)?;??????
- ????????????????}??
- ????????????????input.close()?;???
- ????????????}??
- ????????}??
- ????????zipOut.close()?;??????
- ????}??
- };??
3.2 ZipFile
?
是一个专门表示压缩文件的类。
ZipFile 在实例化的时候必须接收File 类的实例。此File 类的实例是指向一个压缩 *.zip 文件。
第一步:为 ZipFile 实例化
实例化时需要接收File ?类的引用
[java]?view plaincopy
?
- import?java.io.File?;??
- import?java.io.FileInputStream?;??
- import?java.io.InputStream?;??
- import?java.util.zip.ZipEntry?;??
- import?java.util.zip.ZipOutputStream?;??
- import?java.util.zip.ZipFile?;??
- import?java.io.FileOutputStream?;??
- public?class?ZipFileDemo01{??
- ????public?static?void?main(String?args[])?throws?Exception{??????
- ????????File?file?=?new?File("d:"?+?File.separator?+?"mldn.zip")?;????
- ????????ZipFile?zipFile?=?new?ZipFile(file)?;?????
- ????????System.out.println("压缩文件的名称:"?+?zipFile.getName())?;??????
- ????}??
- };??
通过ZipFile 文件,为mldn.zip 进行解压缩操作。
?
[java]?view plaincopy
?
- 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?ZipOutputStreamDemo02{??
- ????public?static?void?main(String?args[])?throws?Exception{??????
- ????????File?file?=?new?File("d:"?+?File.separator?+?"mldn")?;????
- ????????File?zipFile?=?new?File("d:"?+?File.separator?+?"mldndir.zip")?;??????
- ????????InputStream?input?=?null?;????
- ????????ZipOutputStream?zipOut?=?null?;???
- ????????zipOut?=?new?ZipOutputStream(new?FileOutputStream(zipFile))?;??
- ????????zipOut.setComment("www.mldnjava.cn")?;????
- ????????int?temp?=?0?;??
- ????????if(file.isDirectory()){???
- ????????????File?lists[]?=?file.listFiles()?;?????
- ????????????for(int?i=0;i<lists.length;i++){??
- ????????????????input?=?new?FileInputStream(lists[i])?;???
- ????????????????zipOut.putNextEntry(new?ZipEntry(file.getName()??
- ????????????????????+File.separator+lists[i].getName()))?;????
- ????????????????while((temp=input.read())!=-1){???
- ????????????????????zipOut.write(temp)?;??????
- ????????????????}??
- ????????????????input.close()?;???
- ????????????}??
- ????????}??
- ????????zipOut.close()?;??????
- ????}??
- };??
以上的操作中,有一个问题,必须知道压缩文件中的每一个压缩实体的名称才可以进行解压缩操作,而如果现在在假设是一个文件夹呢??
3、ZipInputStream
?
定义:
java.lang.Object
java.io.InputStream
java.io.FilterInputStream
java.util.zip.InflaterInputStream
java.util.zip.ZipInputStream
?
[java]?view plaincopy
?
- import?java.io.File?;??
- import?java.io.FileInputStream?;??
- import?java.io.InputStream?;??
- import?java.util.zip.ZipEntry?;??
- import?java.util.zip.ZipInputStream?;??
- import?java.io.FileInputStream?;??
- public?class?ZipInputStreamDemo01{??
- ????public?static?void?main(String?args[])?throws?Exception{??????
- ????????File?zipFile?=?new?File("d:"?+?File.separator?+?"mldn.zip")?;?????
- ????????ZipInputStream?input?=?null?;?????
- ????????input?=?new?ZipInputStream(new?FileInputStream(zipFile))?;????
- ????????ZipEntry?entry?=?input.getNextEntry()?;???
- ????????System.out.println("压缩实体名称:"?+?entry.getName())?;??
- ????????input.close()?;??
- ????}??
- };??
利用此特性并结合 ZipFile 就可以完成解压缩文件夹的功能。
?
ZipFile 对象,可以找到每一个ZipEntry 的输入流。但是ZipInputStream 并不能得到每一个输入流,所以需要使用ZipFile,但是ZipInputStream ?在取得每一个ZipEntry 的时候,不需要每一个ZipEntry 的时候,不需要每一个ZipEntry 的名称。
[java]?view plaincopy
?
- import?java.io.File?;??
- import?java.io.OutputStream?;??
- import?java.io.InputStream?;??
- import?java.util.zip.ZipEntry?;??
- import?java.util.zip.ZipFile?;??
- import?java.util.zip.ZipInputStream?;??
- import?java.io.FileInputStream?;??
- import?java.io.FileOutputStream?;??
- public?class?ZipInputStreamDemo02{??
- ????public?static?void?main(String?args[])?throws?Exception{??????
- ????????File?file?=?new?File("d:"?+?File.separator?+?"mldndir.zip")?;?????
- ????????File?outFile?=?null?;?????
- ????????ZipFile?zipFile?=?new?ZipFile(file)?;?????
- ????????ZipInputStream?zipInput?=?null?;??????
- ????????OutputStream?out?=?null?;?????
- ????????InputStream?input?=?null?;????
- ????????ZipEntry?entry?=?null?;???
- ????????zipInput?=?new?ZipInputStream(new?FileInputStream(file))?;????
- ????????while((entry?=?zipInput.getNextEntry())!=null){???
- ????????????System.out.println("解压缩"?+?entry.getName()?+?"文件。")?;??
- ????????????outFile?=?new?File("d:"?+?File.separator?+?entry.getName())?;?????
- ????????????if(!outFile.getParentFile().exists()){????
- ????????????????outFile.getParentFile().mkdir()?;?????
- ????????????}??
- ????????????if(!outFile.exists()){????
- ????????????????outFile.createNewFile()?;?????
- ????????????}??
- ????????????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()?;??
- ????}??
- };??
如果目录不存在,则应该进行创建操作。
?
总结:
1、压缩文件中的每一个压缩实体都使用ZipEntry 保存,一个压缩文件中可能包含一个或多个的ZipEntry 对象。
2、在JAVA中可以进行zip、jar、gz、三种格式的压缩支持,操作流程基本上是一样的
3、ZipOutputStream 可以进行压缩输出,但是输出的位置不一定是文件。
4、ZipFile 表示每一个压缩文件,可以得到每一个压缩实体的输入流
5、ZipInputStream 可以得到每一个实体,但是却无法得到每一个实体的输入流。
?
附件为我个人测试用的代码,和文章中提到的方法和思路基本是一致的。
?
附加一段拷贝文件夹的代码:
?
package com.fit.test.io.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Test {
private static void copy(File originalFile, File goalFile)
throws IOException {
if (!goalFile.exists()) {
goalFile.mkdirs();
}
if (originalFile.isFile()) {
copy(originalFile, new File(goalFile, originalFile.getName()));
}
if (originalFile.isDirectory()) {
copyDirectory(originalFile, goalFile);
}
}
private static void copyDirectory(File originalFile, File goalFile)
throws IOException {
File toInDir = new File(goalFile, originalFile.getName());
toInDir.mkdir();
File[] fileList = originalFile.listFiles();
if (fileList == null || fileList.length == 0) {
return;
}
for (int i = 0; i < fileList.length; i++) {
if (fileList[i].isDirectory()) {
copyDirectory(fileList[i], toInDir);
} else if (fileList[i].isFile()) {
copyFile(fileList[i], new File(toInDir, fileList[i].getName()));
}
}
}
private static void copyFile(File originalFile, File goalFile)
throws IOException {
FileInputStream fis = null;
FileOutputStream fos = null;
fis = new FileInputStream(originalFile);
fos = new FileOutputStream(goalFile);
int temp = -1;
byte[] b = new byte[1024];
while ((temp = fis.read(b)) != -1) {
fos.write(b, 0, temp);
}
fos.flush();
fos.close();
fis.close();
}
public static void main(String[] args) throws IOException {
File originalFile = new File("F:\\Work\\apache-ant-1.9.2-bin");
File goalFile = new File("F:\\Work\\back");
copy(originalFile, goalFile);
System.out.println("拷贝完成");
}
}
?
?
?