• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

Java GZip 基于内存实现压缩和解压的方法

java 搞代码 4年前 (2022-01-05) 43次浏览 已收录 0个评论

这篇文章主要介绍了Java GZip 基于内存实现压缩和解压的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

  GZip是常用的无损压缩算法实现,在Linux中较为常见,像我们在Linux安装软件时,基本都是.tar.gz格式。.tar.gz格式文件需要先对目录内文件进行tar压缩,然后使用GZip进行压缩。

  本文针对基于磁盘的压缩和解压进行演示,演示只针对一层目录结构进行,多层目录只需递归操作进行即可。

  Maven依赖

  org.apache.commons: commons-compress: 1.19: 此依赖封装了很多压缩算法相关的工具类,提供的API还是相对比较底层,我们今天在它的基础上做进一步封装。

  org.apache.commonscommons-compress1.19 log4jlog4j1.2.17

  工具类

  在实际应用中,对应不同需求,可能需要生成若干文件,然后将其压缩。在某些应用中,文件较小、文件数量较少且较为固定,频繁与磁盘操作,会带来不必要的效率影响。

  工具类针对.tar.gz格式提供了compressByTar、decompressByTar、compressByGZip、decompressByGZip四个方法,用于处理.tar.gz格式压缩文件,代码如下:

 package com.arhorchin.securitit.compress.gzip; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.Map; 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.io.IOUtils; /** * @author Securitit. * @note 基于内存以ZIP算法进行压缩和解压工具类. */ public class GZipRamUtil { /** * 使用TAR算法进行压缩. * @param sourceFileBytesMap 待压缩文件的Map集合. * @return 压缩后的TAR文件字节数组. * @throws Exception 压缩过程中可能发生的异常,若发生异常,则返回的字节数组长度为0. */ public static byte[] compressByTar(Map tarFileBytesMap) throws Exception { // 变量定义. ByteArrayOutputStream tarBaos = null; TarArchiveOutputStream<p style="color:transparent">来源gao!daima.com搞$代!码网</p> tarTaos = null; TarArchiveEntry tarTae = null; try { // 压缩变量初始化. tarBaos = new ByteArrayOutputStream(); tarTaos = new TarArchiveOutputStream(tarBaos); // // 将文件添加到TAR条目中. for (Map.Entry fileEntry : tarFileBytesMap.entrySet()) { tarTae = new TarArchiveEntry(fileEntry.getKey()); tarTae.setName(fileEntry.getKey()); tarTae.setSize(fileEntry.getValue().length); tarTaos.putArchiveEntry(tarTae); tarTaos.write(fileEntry.getValue()); tarTaos.closeArchiveEntry(); } } finally { if (tarTaos != null) { tarTaos.close(); } if (null == tarBaos) { tarBaos = new ByteArrayOutputStream(); } } return tarBaos.toByteArray(); } /** * 使用TAR算法进行解压. * @param sourceZipFileBytes TAR文件字节数组. * @return 解压后的文件Map集合. * @throws Exception 解压过程中可能发生的异常,若发生异常,返回Map集合长度为0. */ public static Map decompressByTar(byte[] sourceTarFileBytes) throws Exception { // 变量定义. TarArchiveEntry sourceTarTae = null; ByteArrayInputStream sourceTarBais = null; TarArchiveInputStream sourceTarTais = null; Map targetFilesFolderMap = null; try { // 解压变量初始化. targetFilesFolderMap = new HashMap(); sourceTarBais = new ByteArrayInputStream(sourceTarFileBytes); sourceTarTais = new TarArchiveInputStream(sourceTarBais); // 条目解压缩至Map中. while ((sourceTarTae = sourceTarTais.getNextTarEntry()) != null) { targetFilesFolderMap.put(sourceTarTae.getName(), IOUtils.toByteArray(sourceTarTais)); } } finally { if (sourceTarTais != null) sourceTarTais.close(); } return targetFilesFolderMap; } /** * 使用GZIP算法进行压缩. * @param sourceFileBytesMap 待压缩文件的Map集合. * @return 压缩后的GZIP文件字节数组. * @throws Exception 压缩过程中可能发生的异常,若发生异常,则返回的字节数组长度为0. */ public static byte[] compressByGZip(byte[] sourceFileBytes) throws IOException { // 变量定义. ByteArrayOutputStream gzipBaos = null; GzipCompressorOutputStream gzipGcos = null; try { // 压缩变量初始化. gzipBaos = new ByteArrayOutputStream(); gzipGcos = new GzipCompressorOutputStream(gzipBaos); // 采用commons-compress提供的方式进行压缩. gzipGcos.write(sourceFileBytes); } finally { if (gzipGcos != null) { gzipGcos.close(); } if (null == gzipBaos) { gzipBaos = new ByteArrayOutputStream(); } } return gzipBaos.toByteArray(); } /** * 使用GZIP算法进行解压. * @param sourceGZipFileBytes GZIP文件字节数组. * @return 解压后的文件Map集合. * @throws Exception 解压过程中可能发生的异常,若发生异常,则返回的字节数组长度为0. */ public static byte[] decompressByGZip(byte[] sourceGZipFileBytes) throws IOException { // 变量定义. ByteArrayOutputStream gzipBaos = null; ByteArrayInputStream sourceGZipBais = null; GzipCompressorInputStream sourceGZipGcis = null; try { // 解压变量初始化. gzipBaos = new ByteArrayOutputStream(); sourceGZipBais = new ByteArrayInputStream(sourceGZipFileBytes); sourceGZipGcis = new GzipCompressorInputStream(sourceGZipBais); // 采用commons-compress提供的方式进行解压. gzipBaos.write(IOUtils.toByteArray(sourceGZipGcis)); } finally { if (sourceGZipGcis != null) sourceGZipGcis.close(); } return gzipBaos.toByteArray(); } }

工具类测试

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

 package com.arhorchin.securitit.compress.gzip; import java.io.File; import java.util.HashMap; import java.util.Map; import org.apache.commons.io.FileUtils; import com.arhorchin.securitit.compress.gzip.GZipRamUtil; /** * @author Securitit. * @note GZipRamUtil工具类测试. */ public class GZipRamUtilTester { public static void main(String[] args) throws Exception { Map fileBytesMap = null; fileBytesMap = new HashMap(); // 设置文件列表. File dirFile = new File("C:/Users/Administrator/Downloads/个人文件/2020-07-13/files"); for (File file : dirFile.listFiles()) { fileBytesMap.put(file.getName(), FileUtils.readFileToByteArray(file)); } byte[] ramBytes = GZipRamUtil.compressByTar(fileBytesMap); ramBytes = GZipRamUtil.compressByGZip(ramBytes); FileUtils.writeByteArrayToFile(new File("C:/Users/Administrator/Downloads/个人文件/2020-07-13/ram.tar.gz"), ramBytes); ramBytes = GZipRamUtil.decompressByGZip(ramBytes); fileBytesMap = GZipRamUtil.decompressByTar(ramBytes); System.out.println(fileBytesMap.size()); } }

  运行测试后,通过查看ram.tar.gz和控制台输出解压后文件数量,可以确认工具类运行结果无误。

  总结

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

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

到此这篇关于Java GZip 基于内存实现压缩和解压的文章就介绍到这了,更多相关Java GZip 实现压缩和解压内容请搜索gaodaima搞代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持gaodaima搞代码网

以上就是Java GZip 基于内存实现压缩和解压的方法的详细内容,更多请关注gaodaima搞代码网其它相关文章!


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:Java GZip 基于内存实现压缩和解压的方法

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址