java简单实现对文件解压缩
我先贴代码吧!
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
/**
* 压缩文件或解压文件的工具类
* @author yang
*
*/
public class ZipFileAction{
public ZipFileAction(){
}
/**
* 压缩文件
* @param copyZipPath 压缩以后的要存放压缩文件的绝对路径,例如:C:/zipFileName.zip
* @param zipEncoding 压缩文件的文件编码格式,例如:GBK
* @param targetFilePath 要压缩的文件或者文件夹绝对路径,例如:C:/dir/
*/
public void compressFile(String copyZipPath,String zipEncoding
,String targetFilePath) {
ZipOutputStream zos = null;
BufferedInputStream bis = null;
try {
zos=new ZipOutputStream(new FileOutputStream(copyZipPath)
, Charset.forName(zipEncoding));
File itemRoot = new File(targetFilePath);
File[] items = itemRoot.listFiles();
loopCompress(zos, items,"/");// '/' 表示压缩包根目录
}catch(FileNotFoundException e) {
System.err.println("你输入的文件路径有误,请检查文件路径及其后缀是否正确!");
}finally {
closeAll(null,null,null,zos,bis);
}
}
/**
* 循环压缩
* @param zos 压缩文件输出流
* @param items 当前目录的文件(条目)清单
* @param parentDir 当前文件(条目)所在目录
*/
private void loopCompress(ZipOutputStream zos,File[] items,String parentDir) {
BufferedInputStream bis = null;
try {
for(File item:items) {// 第一级目文件录
if(item.isDirectory()) {// 如果是文件夹就进行递归
// 加"/" 表示增加的条目为文件夹
parentDir = parentDir+item.getName()+"/";
zos.putNextEntry(new ZipEntry(parentDir));
File[] newItems = item.listFiles();
// 通过递归完成多级文件压缩
loopCompress(zos, newItems,parentDir);
}else { // 如果是文件就进行压缩
zos.putNextEntry(new ZipEntry(parentDir+item.getName()));
// 一个一个文件的写
bis = new BufferedInputStream(new FileInputStream(item));
byte[] b=new byte[1024];
int len = bis.read(b);
while(len != -1) {
zos.write(b, 0, len);
len = bis.read(b);
}
System.out.println("压缩文件:"+parentDir+item.getName()+" 完成!");
bis.close();//写好一个文件后要关闭流,因为以后没有再对其操作
}
}
}catch(IOException e) {
System.out.println("文件流异常断开!");
}
// 这里不关闭zos流,是因为调用loopCompress方法的方法会关闭,不然会报错Stream closed
}
/**
* 解压文件
* @param zipFilePath 压缩文件的绝对路径,例如:C:/zipFileName.zip
* @param deCompressionPath 解压文件存放的路径,例如:C:/dir/
* @param readEncoding 解压时读出的文件编码格式,例如:GBK
*/
public void decompressionFile(String zipFilePath
,String deCompressionPath,String readEncoding) {
FileOutputStream fos = null;
InputStream is = null;
ZipFile zipFileItems = null;
try {
// 以指定格式打开zip文件
zipFileItems = new ZipFile(zipFilePath
,Charset.forName(readEncoding));
// 获取zip文件的条目
Enumeration<? extends ZipEntry> items = zipFileItems.entries();
while(items.hasMoreElements()) {
// 压缩文件中当前的所操作文件或文件夹的对象
ZipEntry zipCurrentItem = items.nextElement();
/*
zipCurrentItem的具体定位流程演示(每次循环的值)
1)/0_dir.txt
2)/1_dir.txt
3)/2_dir.txt
4)/3_dir.txt
5)/test/0_tes.txt
6)/test/1_tes.txt
7)/test/2_tes.txt
8)/test/3_tes.txt
*/
if(zipCurrentItem.isDirectory()) {// 遇到文件夹时深入文件夹递归
File newFile = new File(deCompressionPath+zipCurrentItem.getName());
if(!newFile.exists()) {
newFile.mkdirs();
}
}else {
// 获取当前条目文件的输入流
is = zipFileItems.getInputStream(zipCurrentItem);
byte[] b = new byte[1024];
File newFile = new File(deCompressionPath+zipCurrentItem.getName());
if(!newFile.exists()) {
new File(deCompressionPath).mkdirs();// 创建路径
newFile.createNewFile();
}
fos = new FileOutputStream(newFile);
int len;
while((len = is.read(b)) != -1) {
fos.write(b, 0, len);
}
System.out.println("解压文件 : "+zipCurrentItem.getName()+" 完成!");
}
}
zipFileItems.close();
}catch (FileNotFoundException e) {
System.err.println("你输入的文件路径有误,请检查文件路径及其后缀是否正确!");
} catch (IOException e) {
System.out.println("文件流异常断开!");
} finally {
closeAll(fos,is,zipFileItems,null,null);
}
}
/**
* 关闭流
* 这个地方的书写特点是,流的关闭顺序一般是从输出流到输入流
* 例如如下代码:
* FileInputStream fis=new FileInputStream("D:/test.txt");
* BufferedInputStream bis=new BufferedInputStream(fis);
* FileOutputStream fos=new FileOutputStream("D:/test1.txt");
* BufferedOutputStream bos=new BufferedOutputStream(fos);
*
* 我们在进行流关闭时是自下而上,所以顺序是bos->fos->bis->fis
*
* 而用该方法来关闭是为了省略代码,技巧在于1)自己知道自己所用流的顺序2)传参数时的小技巧,
* 可以这样调用
* closeAll(fos,null,null,null,null);
* closeAll(null,bis,null,null,null);
* 这样就可以保证顺序不出错了
* @param fos 文件输出流
* @param is 输入流
* @param zf 压缩文件
* @param zos 压缩文件输出流
* @return null
*/
private static void closeAll(FileOutputStream fos,InputStream is,ZipFile zf
,ZipOutputStream zos,BufferedInputStream bis) {
if(null != fos) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != bis) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != zos) {
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != zf) {
try {
zf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
#压缩文件
1)找到目标文件夹及其路径
2)运行代码测试
3)检查是否成功
解压文件
1)找到目标压缩包及其路径
2)运行代码测试
3)检查是否成功
自己只能想到这样写了,可能有很多地方可以修改或精简,望大佬们见谅!!!
这个是zip格式的,jar格式也差不多,我贴个解压jar格式的代码吧
package cn.simple.jre;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class JarFileDecompression {
/**
* 解压jar文件到指定目录
* @param jarFilePath jar文件的绝对路径,例如:D:/test/rt.jar
* @param decompressionJarPath 存放目录的绝对路径,例如:D:/myrt/
*/
public JarFileDecompression(String jarFilePath, String decompressionJarPath) {
JarFile jarFile=null;
File saveDir = new File(decompressionJarPath);
if(saveDir.isDirectory()) {
saveDir.mkdirs();
}
InputStream is = null;
FileOutputStream fos = null;
try {
jarFile = new JarFile(jarFilePath);
Enumeration<JarEntry> jarItems = jarFile.entries();
while(jarItems.hasMoreElements()) {
JarEntry jarItem = jarItems.nextElement();
// 判断是否是文件夹
if(!jarItem.isDirectory()) {
int index = jarItem.getName().lastIndexOf("/");
String dir ="";
if(index > 0) {
dir = jarItem.getName().substring(0, index);
}
new File(decompressionJarPath+dir).mkdirs();
File newFile = new File(decompressionJarPath+jarItem.getName());
if(!newFile.exists()) {
newFile.createNewFile();
}
is = jarFile.getInputStream(jarItem);
fos = new FileOutputStream(newFile);
byte[] b = new byte[1024];
int len;
while((len=is.read(b)) != -1) {
fos.write(b, 0, len);
}
}
System.out.println("解压文件:"+jarItem.getName()+" 完成!");
}
} catch (IOException e) {
e.printStackTrace();
}finally {
if(null != fos) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null != jarFile) {
try {
jarFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}