Java GZip 基于磁盘实现压缩和解压的方法
GZip是常用的无损压缩算法实现,在Linux中较为常见,像我们在Linux安装软件时,基本都是.tar.gz格式。.tar.gz格式文件需要先对目录内文件进行tar压缩,然后使用GZip进行压缩。
本文针对基于磁盘的压缩和解压进行演示,演示只针对一层目录结构进行,多层目录只需递归操作进行即可。
Maven依赖
org.apache.commons:commons-compress:1.19:此依赖封装了很多压缩算法相关的工具类,提供的API还是相对比较底层,我们今天在它的基础上做进一步封装。
org.apache.commons commons-compress 1.19 log4j log4j 1.2.17
其实,在通常情况下,我们都是在磁盘上进行压缩和解压操作的,这样虽然增加了操作的复杂度,但是却无形中避免了一些问题。
工具类针对.tar.gz格式提供了compressByTar、decompressByTar、compressByGZip、decompressByGZip四个方法,用于处理.tar.gz格式压缩文件,代码如下:
packagecom.arhorchin.securitit.compress.gzip;
importjava.io.BufferedInputStream;
importjava.io.BufferedOutputStream;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.FileOutputStream;
importjava.io.IOException;
importorg.apache.commons.compress.archivers.tar.TarArchiveEntry;
importorg.apache.commons.compress.archivers.tar.TarArchiveInputStream;
importorg.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
importorg.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
importorg.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
importorg.apache.commons.compress.utils.IOUtils;
importorg.apache.log4j.Logger;
/**
*@authorSecuritit.
*@note基于磁盘以GZIP算法进行压缩和解压工具类.
*/
publicclassGZipDiskUtil{
/**
*logger.
*/
privatestaticLoggerlogger=Logger.getLogger(GZipDiskUtil.class);
/**
*UTF-8字符集.
*/
publicstaticStringCHARSET_UTF8="UTF-8";
/**
*使用TAR算法进行压缩.
*@paramsourceFolderPath待进行压缩的文件夹路径.
*@paramtargetTarFilePath压缩后的TAR文件存储目录.
*@return压缩是否成功.
*@throwsException压缩过程中可能发生的异常.
*/
publicstaticbooleancompressByTar(StringsourceFolderPath,StringtargetTarFilePath)throwsException{
//变量定义.
FilesourceFolderFile=null;
FileOutputStreamtargetTarFos=null;
TarArchiveOutputStreamtargetTartTaos=null;
TarArchiveEntrytargetTarTae=null;
try{
//压缩变量初始化.
sourceFolderFile=newFile(sourceFolderPath);
targetTarFos=newFileOutputStream(newFile(targetTarFilePath));
targetTartTaos=newTarArchiveOutputStream(targetTarFos);
//将文件添加到ZIP条目中.
for(Filefile:sourceFolderFile.listFiles()){
try(FileInputStreamfis=newFileInputStream(file);
BufferedInputStreambis=newBufferedInputStream(fis);){
targetTarTae=newTarArchiveEntry(file);
targetTarTae.setName(file.getName());
targetTartTaos.putArchiveEntry(targetTarTae);
targetTartTaos.write(IOUtils.toByteArray(bis));
targetTartTaos.closeArchiveEntry();
}
}
}catch(Exceptionex){
logger.info("GZipDiskUtil.compressByTar.",ex);
returnfalse;
}finally{
if(targetTartTaos!=null)
targetTartTaos.close();
if(targetTarFos!=null)
targetTarFos.close();
}
returntrue;
}
/**
*使用TAR算法进行解压.
*@paramsourceTarPath待解压文件路径.
*@paramtargetFolderPath解压后文件夹目录.
*@return解压是否成功.
*@throwsException解压过程中可能发生的异常.
*/
publicstaticbooleandecompressByTar(StringsourceTarPath,StringtargetFolderPath)throwsException{
//变量定义.
FileInputStreamsourceTarFis=null;
TarArchiveInputStreamsourceTarTais=null;
TarArchiveEntrysourceTarTae=null;
FilesingleEntryFile=null;
try{
//解压定义初始化.
sourceTarFis=newFileInputStream(newFile(sourceTarPath));
sourceTarTais=newTarArchiveInputStream(sourceTarFis);
//条目解压缩至指定文件夹目录下.
while((sourceTarTae=sourceTarTais.getNextTarEntry())!=null){
singleEntryFile=newFile(targetFolderPath+File.separator+sourceTarTae.getName());
try(FileOutputStreamfos=newFileOutputStream(singleEntryFile);
BufferedOutputStreambos=newBufferedOutputStream(fos);){
bos.write(IOUtils.toByteArray(sourceTarTais));
}
}
}catch(Exceptionex){
logger.info("GZipDiskUtil.decompressByTar.",ex);
returnfalse;
}finally{
if(sourceTarTais!=null)
sourceTarTais.close();
if(sourceTarFis!=null)
sourceTarFis.close();
}
returntrue;
}
/**
*使用GZIP算法进行压缩.
*@paramsourceFilePath待进行压缩的文件路径.
*@paramtargetGZipFilePath压缩后的GZIP文件存储目录.
*@return压缩是否成功.
*@throwsException压缩过程中可能发生的异常.
*/
publicstaticbooleancompressByGZip(StringsourceFilePath,StringtargetGZipFilePath)throwsIOException{
//变量定义.
FileInputStreamsourceFileFis=null;
BufferedInputStreamsourceFileBis=null;
FileOutputStreamtargetGZipFileFos=null;
BufferedOutputStreamtargetGZipFileBos=null;
GzipCompressorOutputStreamtargetGZipFileGcos=null;
try{
//压缩变量初始化.
sourceFileFis=newFileInputStream(newFile(sourceFilePath));
sourceFileBis=newBufferedInputStream(sourceFileFis);
targetGZipFileFos=newFileOutputStream(targetGZipFilePath);
targetGZipFileBos=newBufferedOutputStream(targetGZipFileFos);
targetGZipFileGcos=newGzipCompressorOutputStream(targetGZipFileBos);
//采用commons-compress提供的方式进行压缩.
targetGZipFileGcos.write(IOUtils.toByteArray(sourceFileBis));
}catch(Exceptionex){
logger.info("GZipDiskUtil.compressByGZip.",ex);
returnfalse;
}finally{
if(targetGZipFileGcos!=null)
targetGZipFileGcos.close();
if(targetGZipFileBos!=null)
targetGZipFileBos.close();
if(targetGZipFileFos!=null)
targetGZipFileFos.close();
if(sourceFileBis!=null)
sourceFileBis.close();
if(sourceFileFis!=null)
sourceFileFis.close();
}
returntrue;
}
/**
*使用GZIP算法进行解压.
*@paramsourceGZipFilePath待解压文件路径.
*@paramtargetFilePath解压后文件路径.
*@return解压是否成功.
*@throws@throwsException解压过程中可能发生的异常.
*/
publicstaticbooleandecompressByGZip(StringsourceGZipFilePath,StringtargetFilePath)throwsIOException{
//变量定义.
FileInputStreamsourceGZipFileFis=null;
BufferedInputStreamsourceGZipFileBis=null;
FileOutputStreamtargetFileFos=null;
GzipCompressorInputStreamsourceGZipFileGcis=null;
try{
//解压变量初始化.
sourceGZipFileFis=newFileInputStream(newFile(sourceGZipFilePath));
sourceGZipFileBis=newBufferedInputStream(sourceGZipFileFis);
sourceGZipFileGcis=newGzipCompressorInputStream(sourceGZipFileBis);
targetFileFos=newFileOutputStream(newFile(targetFilePath));
//采用commons-compress提供的方式进行解压.
targetFileFos.write(IOUtils.toByteArray(sourceGZipFileGcis));
}catch(Exceptionex){
logger.info("GZipDiskUtil.decompressByGZip.",ex);
returnfalse;
}finally{
if(sourceGZipFileGcis!=null)
sourceGZipFileGcis.close();
if(sourceGZipFileBis!=null)
sourceGZipFileBis.close();
if(sourceGZipFileFis!=null)
sourceGZipFileFis.close();
if(targetFileFos!=null)
targetFileFos.close();
}
returntrue;
}
}
在Maven依赖引入正确的情况下,复制上面的代码到项目中,修改package,可以直接使用,下面我们对工具类进行简单测试。测试类代码如下:
packagecom.arhorchin.securitit.compress.gzip;
importcom.arhorchin.securitit.compress.gzip.GZipDiskUtil;
/**
*@authorSecuritit.
*@noteGZipDiskUtil工具类测试.
*/
publicclassGZipDiskUtilTester{
publicstaticvoidmain(String[]args)throwsException{
GZipDiskUtil.compressByTar("C:/Users/Administrator/Downloads/个人文件/2020-07-13/files","C:/Users/Administrator/Downloads/个人文件/2020-07-13/disk.tar");
GZipDiskUtil.compressByGZip("C:/Users/Administrator/Downloads/个人文件/2020-07-13/disk.tar","C:/Users/Administrator/Downloads/个人文件/2020-07-13/disk.tar.gz");
GZipDiskUtil.decompressByGZip("C:/Users/Administrator/Downloads/个人文件/2020-07-13/disk.tar.gz","C:/Users/Administrator/Downloads/个人文件/2020-07-13/disk-untar.tar");
GZipDiskUtil.decompressByTar("C:/Users/Administrator/Downloads/个人文件/2020-07-13/disk-untar.tar","C:/Users/Administrator/Downloads/个人文件/2020-07-13/disk-untar");
}
}
运行测试后,通过查看disk.tar、disk.tar.gz、disk-untar.tar和解压的目录,可以确认工具类运行结果无误。
总结
1)在小文件、文件数量较小且较为固定时,提倡使用内存压缩和解压方式。使用内存换时间,减少频繁的磁盘操作。《JavaGZip基于内存实现压缩和解压》
2)在大文件、文件数量较大时,提倡使用磁盘压缩和解压方式。过大文件对服务会造成过度的负载,磁盘压缩和解压可以缓解这种压力。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。