Java压缩技术的学习

由于工作的需要,经常要手动去打上线安装包,为了方便,自己写程序去帮助打包。使用过Unix或者Linux的人都基本上都用过tar打包以及gzip压缩,但在Windows下使用得最多的压缩还是RAR和Zip压缩吧

一、        tar打包、解包

在java的JDK中没有原生的tar归档类,需要下载开源的包: commons-compress-1.0.jar,所以

第一步是下载jar包,可以到www.findjar.com搜索并下载。

第二步导入到工程中;忽略

第三步编写源代码,在写代码之前使用介绍一下

//打包归档输出流

org.apache.commons.compress.archivers.tar.TarArchiveOutputStream

//解包归档输入流

org.apache.commons.compress.archivers.tar.TarArchiveInputStream

//增加打包归档的条目

void org.apache.commons.compress.archivers.tar.TarArchiveOutputStream.putArchiveEntry(ArchiveEntry arg0)

//设置归档的模式:

TarArchiveOutputStream.LONGFILE_GNU和TarArchiveOutputStream.LONGFILE_ERROR和TarArchiveOutputStream.LONGFILE_TRUNCATE

void org.apache.commons.compress.archivers.tar.TarArchiveOutputStream.setLongFileMode(int longFileMode)

//获取归档文件中的条目

TarArchiveEntry org.apache.commons.compress.archivers.tar.TarArchiveInputStream.getNextTarEntry() throws IOException


 

下面是打包的源代码:

        /**

	 * tar 打包

	 * @param source 源文件

	 * @param dest 目标文件

	 */

	public static void tar(File source){

		logger.info("开始对源文件["+source.getName()+"]打成tar包");

		FileOutputStream out = null;

		TarArchiveOutputStream tarOut = null;

		

		String parentPath = source.getParent();

		File dest = new File(parentPath + source.getName() + ".tar");

		try{

			out = new FileOutputStream(dest);

			tarOut = new TarArchiveOutputStream(out);

			//解决文件名过长

			tarOut.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);

			tarPack(source, tarOut,"");

			tarOut.flush();

			tarOut.close();

			logger.info("成功把源文件打为tar包,名称为:["+dest.getName()+"]");

		}catch (Exception e) {

			logger.error(e.getMessage(),e);

		}finally{

			try{

				if(out != null){

					out.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

			try{

				if(tarOut != null){

					tarOut.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

		}

	}

	/**

	 * 归档

	 * @param source 源文件或者目录

	 * @param tarOut 归档流

	 * @param parentPath 归档后的目录或者文件路径

	 */

	public static void tarPack(File source,TarArchiveOutputStream tarOut,String parentPath){

		if(source.isDirectory()){

			tarDir(source,tarOut,parentPath);

		}else if(source.isFile()){

			tarFile(source,tarOut,parentPath);

		}

	}

	/**

	 * 归档文件(非目录)

	 * @param source 源文件

	 * @param tarOut 归档流

	 * @param parentPath 归档后的路径 

	 */

	public static void tarFile(File source,TarArchiveOutputStream tarOut,String parentPath){

		TarArchiveEntry entry = new TarArchiveEntry(parentPath + source.getName());

		BufferedInputStream bis = null;

		FileInputStream fis = null;

		try {

			entry.setSize(source.length());

			tarOut.putArchiveEntry(entry);

			fis = new FileInputStream(source);

			bis = new BufferedInputStream(fis);

			int count = -1;

			byte []buffer = new byte[1024];

			while((count = bis.read(buffer, 0, 1024)) != -1){

				tarOut.write(buffer, 0, count);

			}

			bis.close();

			tarOut.closeArchiveEntry();

		} catch (IOException e) {

			logger.error(e.getMessage(),e);

		}finally{

			try {

				if(bis != null){

					bis.close();

				}

			} catch (Exception e2) {

				e2.printStackTrace();

			}

			try {

				if(fis != null){

					fis.close();

				}

			} catch (Exception e2) {

				e2.printStackTrace();

			}

		}

	}

	/**

	 * 归档目录

	 * @param sourceDir 原目录

	 * @param tarOut 归档流

	 * @param parentPath 归档后的父目录

	 */

	public static void tarDir(File sourceDir,TarArchiveOutputStream tarOut,String parentPath){

		//归档空目录

		if(sourceDir.listFiles().length < 1){

			TarArchiveEntry entry = new TarArchiveEntry(parentPath + sourceDir.getName() + "\\");

			try {

				tarOut.putArchiveEntry(entry);

				tarOut.closeArchiveEntry();

			} catch (IOException e) {

				logger.error(e.getMessage(),e);

			}

		}

		//递归 归档

		for (File file : sourceDir.listFiles()) {

			tarPack(file, tarOut,parentPath + sourceDir.getName() + "\\");

		}

	}


 

以下解包的源代码

/**

	 * 解归档

	 * @param source 源归档tar文件

	 */

	public static void untar(File source){

		TarArchiveInputStream tarIn = null;

		FileInputStream fis = null;

		String parentPath = source.getParent();

		

		BufferedOutputStream bos = null;

		FileOutputStream fos = null;

		try{

			fis = new FileInputStream(source);

			tarIn = new TarArchiveInputStream(fis);

			TarArchiveEntry entry = null;

			while((entry = tarIn.getNextTarEntry()) != null){

				File file = new File(parentPath + "\\" + entry.getName());

              //为解决空目录

              if(entry.isDirectory()){

					file.mkdirs();

					continue;

				}

				File parentDir = file.getParentFile();

				if(!parentDir.exists()){

					parentDir.mkdirs();

				}

				

				fos = new FileOutputStream(file);

				bos = new BufferedOutputStream(fos);

				int count = -1;

				byte []buffer = new byte[1024];

				while((count = tarIn.read(buffer, 0, buffer.length)) != -1){

					bos.write(buffer, 0, count);

				}

				bos.flush();

				bos.close();

				fos.close();

			}

		}catch (Exception e) {

			logger.error(e.getMessage(),e);

		}finally{

			try{

				if(fis != null){

					fis.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

			try{

				if(fos != null){

					fos.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

			try{

				if(bos != null){

					bos.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

			try{

				if(tarIn != null){

					tarIn.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

		}

	}


 

二、        gzip压缩、解压

注意gzip不支持压缩目录的;Jdk里提供了类支持压缩文件;默认生成.gz文件

主要对应的Java类为:

//Gzip输入流

java.util.zip.GZIPInputStream

//Gzip输出流

java.util.zip.GZIPOutputStream


 

压缩源代码

/**

	 * gzip 压缩,跟源文件在相同目录中生成.gz文件

	 * @param source 源文件

	 */

	public static void gzip(File source){

		logger.info("开始对源文件["+source.getName()+"]压缩成.gz包");

		String dir = source.getParent();

		File target = new File(dir + "\\" +source.getName() + ".gz");

		FileInputStream fis = null;

		FileOutputStream fos = null;

		GZIPOutputStream gzipOS = null;

		try{

			fis = new FileInputStream(source);

			fos = new FileOutputStream(target);

			gzipOS = new GZIPOutputStream(fos);

			int count = -1;

			byte [] buffer = new byte[1024];

			while((count = fis.read(buffer, 0, buffer.length)) != -1){

				gzipOS.write(buffer, 0, count);

			}

			gzipOS.flush();

			gzipOS.close();

			logger.info("成功把源文件["+source.getName()+"]压缩为.gz包["+target.getName()+"]");

		}catch (Exception e) {

			logger.error(e.getMessage(),e);

		}finally{

			try{

				if(fis!=null){

					fis.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

			try{

				if(fos!=null){

					fos.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

			try{

				if(gzipOS!=null){

					gzipOS.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

		}

	}


 

解压.gz包源代码

/**

	 * 解压.gz包

	 * @param source 源.gz包

	 */

	public static void ungzip(File source){

		GZIPInputStream gzipIS = null;

		FileInputStream fis = null;

		FileOutputStream fos = null;

		BufferedOutputStream bos = null;

		

		String fileName = source.getName();

		fileName = fileName.substring(0, fileName.lastIndexOf("."));

		try{

			fis = new FileInputStream(source);

			gzipIS = new GZIPInputStream(fis);

			File target = new File(source.getParent() + "\\" + fileName);

			fos = new FileOutputStream(target);

			bos = new BufferedOutputStream(fos);

			

			int count = -1;

			byte []buffer = new byte[1024];

			while((count = gzipIS.read(buffer, 0, buffer.length)) != -1){

				bos.write(buffer, 0, count);

			}

			bos.flush();

		}catch (Exception e) {

			logger.error(e.getMessage(),e);

		}finally{

			try{

				if(fis!=null){

					fis.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

			try{

				if(fos!=null){

					fos.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

			try{

				if(bos != null){

					bos.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

			try{

				if(gzipIS!=null){

					gzipIS.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

		}

	}


 

 

三、        zip压缩、解压

Jdk提供代码技术支持,tar打包跟zip压缩类似的。

在Jdk中主要的类为:

java.util.zip.ZipOutputStream

java.util.zip.ZipInputStream

 

压缩源代码

/**

	 * 使用zip压缩文件

	 * @param source 源文件或者文件夹

	 */

	public static void zip(File source){

		String dir = source.getParent();

		File target = new File(dir + "\\" +source.getName() + ".zip");

		FileOutputStream fos = null;

		ZipOutputStream zipos = null;

		

		try{

			fos = new FileOutputStream(target);

			zipos = new ZipOutputStream(fos);

			zipFile(source, zipos, "");

			//必须要下面一步,否则会报no such file or directory错误

			zipos.close();

		}catch (Exception e) {

			logger.error(e.getMessage(),e);

		}finally{

			try {

				if(fos != null){

					fos.close();

				}

			} catch (Exception e2) {

				e2.printStackTrace();

			}

			try {

				if(zipos != null){

					zipos.close();

				}

			} catch (Exception e2) {

				e2.printStackTrace();

			}

		}

	}

	/**

	 * 递归压缩文件或者文件夹

	 * @param source 源文件

	 * @param zipos zip输出流

	 * @param parentPath 路径 

	 */

	public static void zipFile(File source,ZipOutputStream zipos,String parentPath){

		FileInputStream fis = null;

		BufferedInputStream bis = null;

		try {

			//增加目录 

			if(source.isDirectory()){

				File[]files = source.listFiles();

				if(files.length < 1){

					ZipEntry entry = new ZipEntry(parentPath + source.getName()  + "/");

					zipos.putNextEntry(entry);

				}

				for (File file : files) {

					zipFile(file, zipos, parentPath + source.getName() + "/");

				}

			}else if(source.isFile()){

				fis = new FileInputStream(source);

				bis = new BufferedInputStream(fis);

				ZipEntry entry = new ZipEntry(parentPath + source.getName());

				zipos.putNextEntry(entry);

				int count = -1;

				byte []buffer = new byte[1024];

				while((count = bis.read(buffer, 0, buffer.length)) != -1){

					zipos.write(buffer, 0, count);

				}

				fis.close();

				bis.close();

			}

		} catch (IOException e) {

			logger.error(e.getMessage(),e);

		}finally{

			try {

				if(bis != null){

					bis.close();

				}

			} catch (Exception e2) {

				e2.printStackTrace();

			}

			try {

				if(fis != null){

					fis.close();

				}

			} catch (Exception e2) {

				e2.printStackTrace();

			}

		}

	}


 

解压源代码

/**

	 * 解压zip文件

	 * @param source 源.zip文件

	 */

	public static void unzip(File source){

		ZipInputStream zipIn = null;

		FileInputStream fis = null;

		String parentPath = source.getParent();

		

		System.out.println(parentPath);

		BufferedOutputStream bos = null;

		FileOutputStream fos = null;

		try{

			fis = new FileInputStream(source);

			zipIn = new ZipInputStream(fis);

			ZipEntry entry = null;

			while((entry = zipIn.getNextEntry()) != null){

				File file = new File(parentPath + "\\" + entry.getName());

				

				//为了空目录的出现

				if(entry.isDirectory()){

					file.mkdirs();

					continue;

				}

				

				File parentDir = file.getParentFile();

				if(!parentDir.exists()){

					parentDir.mkdirs();

				}

				fos = new FileOutputStream(file);

				bos = new BufferedOutputStream(fos);

				int count = -1;

				byte []buffer = new byte[1024];

				while((count = zipIn.read(buffer, 0, buffer.length)) != -1){

					bos.write(buffer, 0, count);

				}

				bos.flush();

				bos.close();

				fos.close();

			}

			zipIn.close();

		}catch (Exception e) {

			logger.error(e.getMessage(),e);

		}finally{

			try{

				if(fis != null){

					fis.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

			try{

				if(fos != null){

					fos.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

			try{

				if(bos != null){

					bos.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

			try{

				if(zipIn != null){

					zipIn.close();

				}

			}catch (Exception e) {

				logger.error(e.getMessage(),e);

			}

		}

	}


 

 

 

 

 

你可能感兴趣的:(java压缩)