时间:2021-05-20
GZip是常用的无损压缩算法实现,在Linux中较为常见,像我们在Linux安装软件时,基本都是.tar.gz格式。.tar.gz格式文件需要先对目录内文件进行tar压缩,然后使用GZip进行压缩。
本文针对基于磁盘的压缩和解压进行演示,演示只针对一层目录结构进行,多层目录只需递归操作进行即可。
Maven依赖
org.apache.commons: commons-compress: 1.19: 此依赖封装了很多压缩算法相关的工具类,提供的API还是相对比较底层,我们今天在它的基础上做进一步封装。
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId> <version>1.19</version></dependency><dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version></dependency>工具类
在实际应用中,对应不同需求,可能需要生成若干文件,然后将其压缩。在某些应用中,文件较小、文件数量较少且较为固定,频繁与磁盘操作,会带来不必要的效率影响。
工具类针对.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<String, byte[]> tarFileBytesMap) throws Exception { // 变量定义. ByteArrayOutputStream tarBaos = null; TarArchiveOutputStream tarTaos = null; TarArchiveEntry tarTae = null; try { // 压缩变量初始化. tarBaos = new ByteArrayOutputStream(); tarTaos = new TarArchiveOutputStream(tarBaos); // // 将文件添加到TAR条目中. for (Map.Entry<String, byte[]> 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<String, byte[]> decompressByTar(byte[] sourceTarFileBytes) throws Exception { // 变量定义. TarArchiveEntry sourceTarTae = null; ByteArrayInputStream sourceTarBais = null; TarArchiveInputStream sourceTarTais = null; Map<String, byte[]> targetFilesFolderMap = null; try { // 解压变量初始化. targetFilesFolderMap = new HashMap<String, byte[]>(); 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<String, byte[]> fileBytesMap = null; fileBytesMap = new HashMap<String, byte[]>(); // 设置文件列表. 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 实现压缩和解压内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
1.命令简介gzip(GNUzip)命令用来压缩和解压缩文件,是在Linux系统中经常使用的一个对文件进行压缩和解压缩的命令,采用LZ77无损压缩算法,压缩后的
linux下gzip的压缩详解Linux压缩保留源文件的方法:gzip–cfilename>filename.gzLinux解压缩保留源文件的方法:gunzip
gzip压缩使用gzip压缩可以降低网站带宽消耗,同时提升访问速度。主要在nginx服务端将页面进行压缩,然后在浏览器端进行解压和解析,目前大多数流行的浏览器都
本文实例为大家分享了java实现文件夹解压和压缩的具体代码,供大家参考,具体内容如下效果实现多个文件以及文件夹的压缩和解压代码分析importjava.io.F
本文实例讲述了C#实现压缩和解压缩的方法。分享给大家供大家参考,具体如下:使用ICSharpCode.SharpZipLib.dll来压缩/解压(压缩效率比GZ