由于工作的需要,经常要手动去打上线安装包,为了方便,自己写程序去帮助打包。使用过Unix或者Linux的人都基本上都用过tar打包以及gzip压缩,但在Windows下使用得最多的压缩还是RAR和Zip压缩吧
在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不支持压缩目录的;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); } } }
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); } } }