java简单实现对文件解压缩

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();
				}
			}
		}
		
		
	}

}

猜你喜欢

转载自blog.csdn.net/qq_43209531/article/details/87887423