本篇文章为大家展示了Java使用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如何实现文件的压缩和解压,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。