java tar.gz 格式多文件打包压缩与解压
2017-09-06 10:19
609 查看
问题背景:开发中,我们时常会遇到对文件进行存储或传输的问题,但如果传输储存的文件较大,浪费磁盘空间不说,还会大大影响程序运行效率。于是便引出了这篇文章的主题,关于文件打包与压缩的问题。这里“打包”是指,将多个文件合成一个文件;“压缩”是指,把文件的二进制代码压缩,把相邻的0,1代码减少,比如有000000,可以把它变成6个0 的写法60,来减少该文件的空间。
举例:在PC端中,有很多压缩软件,如:WinRAR、2345好压等。他们通常是将文件打包与压缩和为一体执行的。简单来说,当我们要压缩的文件夹里包含多个文件时,压缩软件会先将文件夹打包成一个文件后再进行二进制代码压缩。就像Linux中 tar 与 gzip 命令一样,一个负责打包,一个负责压缩。
压缩率: bz2 > gz > zip。看到这里,可能有人会问,为什么没有.rar格式的文件呢?那是因为,.rar格式是一种文件压缩与归档的私有专利压缩格式。其作者,仅有条件的公开了解码程序的源代码,但是编码程序仍然是私有的。(PS:由于zip文件压缩率太低所以很少被使用,但zip格式文件也是有优点的,最明显的是,.zip格式的文件可以在Windows和Linux中不安装任何解压软件的情况下解压。)
说了这么多,接下来我们就开始动手吧!
依赖jar包: commons-compress-1.12.jar
代码:
结语: 最后,细心的人可能会问,上文中说 .bz2 格式的文件为压缩率最高的文件,可为什么没有选择 .bz2 格式进行文件压缩。这里我想说明的是,可能是因为两种压缩算法不同的原因, 当我对一个139M的文件夹进行打包压缩时,使用.bz2算法压缩需要35秒的时间,而当我使用.gz格式的文件只需要15秒的时间,且文件大小仅差3M。因此,综合考虑后,我选择了.gz格式的压缩文件。
相关连接:
Java压缩技术(六) BZIP2——Commons实现
Java实现将多个文件打包压缩成tar.gz文件
以上两个连接均为本人学习压缩与解压时曾参考过的文章,非本人所写。
举例:在PC端中,有很多压缩软件,如:WinRAR、2345好压等。他们通常是将文件打包与压缩和为一体执行的。简单来说,当我们要压缩的文件夹里包含多个文件时,压缩软件会先将文件夹打包成一个文件后再进行二进制代码压缩。就像Linux中 tar 与 gzip 命令一样,一个负责打包,一个负责压缩。
压缩率: bz2 > gz > zip。看到这里,可能有人会问,为什么没有.rar格式的文件呢?那是因为,.rar格式是一种文件压缩与归档的私有专利压缩格式。其作者,仅有条件的公开了解码程序的源代码,但是编码程序仍然是私有的。(PS:由于zip文件压缩率太低所以很少被使用,但zip格式文件也是有优点的,最明显的是,.zip格式的文件可以在Windows和Linux中不安装任何解压软件的情况下解压。)
说了这么多,接下来我们就开始动手吧!
依赖jar包: commons-compress-1.12.jar
代码:
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; import org.apache.commons.io.IOUtils; /** * 多文件压缩与解压 * @author Supreme_Sir */ public class Compress { private final static int BUFFER = 1048576; /** * 解压tar.gz文件 * @param tar_gz * @param sourceFolder */ public void decompress(File tar_gz,String sourceFolder){ FileInputStream fis = null; BufferedInputStream bis = null; GZIPInputStream gzis = null; TarArchiveInputStream tais = null; OutputStream out = null; try { fis = new FileInputStream(tar_gz); bis = new BufferedInputStream(fis); gzis = new GZIPInputStream(bis); tais = new TarArchiveInputStream(gzis); TarArchiveEntry tae = null; boolean flag = false; while((tae = tais.getNextTarEntry()) != null ){ File tmpFile = new File(sourceFolder+tae.getName()); if(! flag){ //使用 mkdirs 可避免因文件路径过多而导致的文件找不到的异常 new File(tmpFile.getParent()).mkdirs(); flag = true; } out = new FileOutputStream(tmpFile); int length = 0; byte[] b = new byte[BUFFER]; while((length = tais.read(b)) != -1){ out.write(b, 0, length); } } } catch (Exception e) { e.printStackTrace(); }finally{ try { if(tais != null) tais.close(); if(gzis != null) gzis.close(); if(bis != null) bis.close(); if(fis != null) fis.close(); if(out != null){ out.flush(); out.close(); } } catch (Exception e) { e.printStackTrace(); } } } /** * 压缩tar文件 * @param list * @param outPutPath * @param fileName */ public File compresser(ArrayList<File> list,String outPutPath,String fileName){ File outPutFile = null; FileInputStream fis = null; BufferedInputStream bis = null; FileOutputStream fos = null; GZIPOutputStream gzp = null; File tar = new File("C:/temp.tar"); try { fis = new FileInputStream(pack(list,tar)); bis = new BufferedInputStream(fis,BUFFER); outPutFile = new File(outPutPath+"/"+fileName+".tar.gz"); fos = new FileOutputStream(outPutFile); gzp = new GZIPOutputStream(fos); int count; byte data[] = new byte[BUFFER]; while ((count = bis.read(data, 0, BUFFER)) != -1) { gzp.write(data, 0, count); } } catch (Exception e) { e.printStackTrace(); }finally{ try { if(gzp != null){ gzp.finish(); gzp.flush(); gzp.close(); } if(fos != null) fos.close(); if(bis != null) bis.close(); if(fis != null) fis.close(); if(tar.exists()){ tar.delete(); } } catch (Exception e) { e.printStackTrace(); } } return outPutFile; } /** * 私有函数将文件集合压缩成tar包后返回 * @param files 要压缩的文件集合 * @param target tar.输出流的目标文件 * @return File 指定返回的目标文件 */ private File pack(ArrayList<File> files, File target){ FileOutputStream fos = null; BufferedOutputStream bos = null; TarArchiveOutputStream taos = null; FileInputStream fis = null; try { fos = new FileOutputStream(target); bos = new BufferedOutputStream(fos,BUFFER); taos = new TarArchiveOutputStream(bos); //解决文件名过长问题 taos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU); for(File file : files){ taos.putArchiveEntry(new TarArchiveEntry(file)); fis = new FileInputStream(file); IOUtils.copy(fis, taos); taos.closeArchiveEntry(); } } catch (Exception e) { e.printStackTrace(); }finally{ try { if(fis != null) fis.close(); if(taos != null){ taos.finish(); taos.flush(); taos.close(); } if(bos != null){ bos.flush(); bos.close(); } if(fos != null){ fos.flush(); fos.close(); } } catch (Exception e) { e.printStackTrace(); } } return target; } }
结语: 最后,细心的人可能会问,上文中说 .bz2 格式的文件为压缩率最高的文件,可为什么没有选择 .bz2 格式进行文件压缩。这里我想说明的是,可能是因为两种压缩算法不同的原因, 当我对一个139M的文件夹进行打包压缩时,使用.bz2算法压缩需要35秒的时间,而当我使用.gz格式的文件只需要15秒的时间,且文件大小仅差3M。因此,综合考虑后,我选择了.gz格式的压缩文件。
相关连接:
Java压缩技术(六) BZIP2——Commons实现
Java实现将多个文件打包压缩成tar.gz文件
以上两个连接均为本人学习压缩与解压时曾参考过的文章,非本人所写。
相关文章推荐
- java tar.gz 格式多文件打包压缩与解压
- 使用Python3解压gz、tar、tgz、zip、rar五种格式的压缩文件例子
- zip, tar, tar.gz, tar.bz2, jar,7z等格式文件的压缩和解压方法
- Java实现将多个文件打包压缩成tar.gz文件
- java 压缩以及解压文件,tar,zip,gz(gizp)
- zip, tar, tar.gz, tar.bz2, jar,7z等格式文件的压缩和解压方法
- JAVA 解压tar.gz格式文件
- Linux 下tar,bz2,gz,xz等各种格式压缩文件的压缩与解压
- java 压缩以及解压文件,有tar,zip,gz(gizp)和解压
- Tar -T(大写) 打包压缩和解压命令的文件的格式规范
- java不解压读取linux服务器上的zip以及tar.gz压缩文件
- Linux压缩解压 tar.gz格式的文件
- [置顶] 使用Python3解压gz、tar、tgz、zip、rar五种格式的压缩文件例子
- Windows下如何将文件打包压缩成 .tar.gz格式
- java压缩文件成tar.gz格式
- linux下如何打包压缩?解包解压?.tar文件.gz文件
- 关于windows下C++实现解压、压缩 .tar.gz文件
- Linux操作系统中,*.zip、*.tar、*.tar.gz、*.tar.bz2、*.tar.xz、*.jar、*.7z等格式的压缩与解压
- Linux操作系统中,*.zip、*.tar、*.tar.gz、*.tar.bz2、*.tar.xz、*.jar、*.7z等格式的压缩与解压
- php解压 tar.gz 格式文件