Java GZip 基于磁盘实现压缩和解压的方法

网友投稿 399 2022-11-25


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格式压缩文件,代码如下:

package com.arhorchin.securitit.compress.gzip;

import java.io.BufferedInputStream;

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

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.compress.compressors.gzip.GzipCompressorInputStream;

import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;

import org.apache.commons.compress.utils.IOUtils;

import org.apache.log4j.Logger;

/**

* @author Securitit.

* @note 基于磁盘以GZIP算法进行压缩和解压工具类.

*/

public class GZipDiskUtil {

/**

* logger.

*/

private static Logger logger = Logger.getLogger(GZipDiskUtil.class);

/**

* UTF-8字符集.

*/

public static String CHARSET_UTF8 = "UTF-8";

/**

* 使用TAR算法进行压缩.

* @param sourceFolderPath 待进行压缩的文件夹路径.

* @param targetTarFilePath 压缩后的TAR文件存储目录.

* @return 压缩是否成功.

* @throws Exception 压缩过程中可能发生的异常.

*/

public static boolean compressByTar(String sourceFolderPath, String targetTarFilePath) throws Exception {

// 变量定义.

File sourceFolderFile = null;

FileOutputStream targetTarFos = null;

TarArchiveOutputStream targetTartTaos = null;

TarArchiveEntry targetTarTae = null;

try {

// 压缩变量初始化.

sourceFolderFile = new File(sourceFolderPath);

targetTarFos = new FileOutputStream(new File(targetTarFilePath));

targetTartTaos = new TarArchiveOutputStream(targetTarFos);

// 将文件添加到ZIP条目中.

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

try (FileInputStream fis = new FileInputStream(file);

BufferedInputStream bis = new BufferedInputStream(fis);) {

targetTarTae = new TarArchiveEntry(file);

targetTarTae.setName(file.getName());

targetTartTaos.putArchiveEntry(targetTarTae);

targetTartTaos.write(IOUtils.toByteArray(bis));

targetTartTaos.closeArchiveEntry();

}

}

} catch (Exception ex) {

logger.info("GZipDiskUtil.compressByTar.", ex);

return false;

} finally {

if (targetTartTaos != null)

targetTartTaos.close();

if (targetTarFos != null)

targetTarFos.close();

}

return true;

}

/**

* 使用TAR算法进行解压.

* @param sourceTarPath 待解压文件路径.

* @param targetFolderPath 解压后文件夹目录.

* @return 解压是否成功.

* @throws Exception 解压过程中可能发生的异常.

*/

public static boolean decompressByTar(String sourceTarPath, String targetFolderPath) throws Exception {

// 变量定义.

FileInputStream sourceTarFis = null;

TarArchiveInputStream sourceTarTais = null;

TarArchiveEntry sourceTarTae = null;

File singleEntryFile = null;

try {

// 解压定义初始化.

sourceTarFis = new FileInputStream(new File(sourceTarPath));

sourceTarTais = new TarArchiveInputStream(sourceTarFis);

// 条目解压缩至指定文件夹目录下.

while ((sourceTarTae = sourceTarTais.getNextTarEntry()) != null) {

singleEntryFile = new File(targetFolderPath + File.separator + sourceTarTae.getName());

try (FileOutputStream fos = new FileOutputStream(singleEntryFile);

BufferedOutputStream bos = new BufferedOutputStream(fos);) {

bos.write(IOUtils.toByteArray(sourceTarTais));

}

}

} catch (Exception ex) {

logger.info("GZipDiskUtil.decompressByTar.", ex);

return false;

} finally {

if (sourceTarTais != null)

sourceTarTais.close();

if (sourceTarFis != null)

sourceTarFis.close();

}

return true;

}

/**

* 使用GZIP算法进行压缩.

* @param sourceFilePath 待进行压缩的文件路径.

* @param targetGZipFilePath 压缩后的GZIP文件存储目录.

* @return 压缩是否成功.

* @throws Exception 压缩过程中可能发生的异常.

*/

public static boolean compressByGZip(String sourceFilePath, String targetGZipFilePath) throws IOException {

// 变量定义.

FileInputStream sourceFileFis = null;

BufferedInputStream sourceFileBis = null;

FileOutputStream targetGZipFileFos = null;

BuRMweGLVfferedOutputStream targetGZipFileBos = null;

GzipCompressorOutputStream targetGZipFileGcos = null;

try {

// 压缩变量初始化.

sourceFileFis = new FileInputStream(new File(sourceFilePath));

sourceFileBis = new BufferedInputStream(sourceFileFis);

targetGZipFileFos = new FileOutputStream(targetGZipFilePath);

targetGZipFileBos = new BufferedOutputStream(targetGZipFileFos);

targetGZipFileGcos = new GzipCompressorOutputStream(targetGZipFileBos);

http://// 采用commons-compress提供的方式进行压缩.

targetGZipFileGcos.write(IOUtils.toByteArray(sourceFileBis));

} catch (Exception ex) {

logger.info("GZipDiskUtil.compressByGZip.", ex);

return false;

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

}

return true;

}

/**

* 使用GZIP算法进行解压.

* @param sourceGZipFilePath 待解压文件路径.

* @param targetFilePath 解压后文件路径.

* @return 解压是否成功.

* @throws @throws Exception 解压过程中可能发生的异常.

*/

public static boolean decompressByGZip(String sourceGZipFilePath, String targetFilePath) throws IOException {

// 变量定义.

FileInputStream sourceGZipFileFis = null;

BufferedInputStream sourceGZipFileBis = null;

FileOutputStream targetFileFos = null;

GzipCompressorInputStream sourceGZipFileGcis = null;

try {

// 解压变量初始化.

sourceGZipFileFis = new FileInputStream(new File(sourceGZipFilePath));

sourceGZipFileBis = new BufferedInputStream(sourceGZipFileFis);

sourceGZipFileGcis = new GzipCompressorInputStream(sourceGZipFileBis);

targetFileFos = new FileOutputStream(new File(targetFilePath));

// 采用commons-compress提供的方式进行解压.

targetFileFos.write(IOUtils.toByteArray(sourceGZipFileGcis));

} catch (Exception ex) {

logger.info("GZipDiskUtil.decompressByGZip.", ex);

return false;

} finally {

if (sourceGZipFileGcis != null)

sourceGZipFileGcis.close();

if (sourceGZipFileBis != null)

sourceGZipFileBis.close();

if (sourceGZipFileFis != null)

sourceGZipFileFis.close();

if (targetFileFos != null)

targetFileFos.close();

}

return true;

}

}

工具类测试

在Maven依赖引入正确的情况下,复制上面的代码到项目中,修改package,可以直接使用,下面我们对工具类进行简单测试。测试类代码如下:

package com.arhorchin.securitit.compress.gzip;

import com.arhorchin.securitit.compress.gzip.GZipDiskUtil;

/**

* @author Securitit.

* @note GZipDiskUtil工具类测试.

*/

public class GZipDiskUtilTester {

public static void main(String[] args) throws Exception {

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");

}

}

195; 运行测试后,通过查看disk.tar、disk.tar.gz、disk-untar.tar和解压的目录,可以确认工具类运行结果无误。

总结

1) 在小文件、文件数量较小且较为固定时,提倡使用内存压缩和解压方式。使用内存换时间,减少频繁的磁盘操作。《Java GZip 基于内存实现压缩和解压》

2) 在大文件、文件数量较大时,提倡使用磁盘压缩和解压方式。过大文件对服务会造成过度的负载,磁盘压缩和解压可以缓解这种压力。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java lambda list转换map时,把多个参数拼接作为key操作
下一篇:Java GZip 基于内存实现压缩和解压的方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~