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

欢迎大家关注本博,同时欢迎大家评论交流,可以给个赞哦!!!

  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 实现压缩和解压内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • java 压缩和解压缩Zip、Jar、Gzip文件实例代码

    我们经常会使用WinZIP等压缩软件将文件进行压缩以方便传输.在java里面也提供了将文件进行压缩以减少传输时的数据量的类,可以很方便的将文件压缩成ZIP.JAR.GZIP等形式,GZIP主要是在Linux系统下的压缩文件. 下面主要讲的就是ZIP形式的压缩文件,而JAR.GZIP形式的压缩文件也是类似的用法. ZIP是一种很常见的压缩形式,在java中要实现ZIP的压缩主要用到的是java.util.zip这个包里面的类.主要有ZipFile. ZipOutputStream.ZipInput

  • Java实现文件压缩与解压的示例[zip格式,gzip格式]

    Java实现ZIP的解压与压缩功能基本都是使用了Java的多肽和递归技术,可以对单个文件和任意级联文件夹进行压缩和解压,对于一些初学者来说是个很不错的实例. zip扮演着归档和压缩两个角色:gzip并不将文件归档,仅只是对单个文件进行压缩,所以,在UNIX平台上,命令tar通常用来创建一个档案文件,然后命令gzip来将档案文件压缩. Java I/O类库还收录了一些能读写压缩格式流的类.要想提供压缩功能,只要把它们包在已有的I/O类的外面就行了.这些类不是Reader和Writer,而是Inpu

  • java使用gzip实现文件解压缩示例

    复制代码 代码如下: package com.cjonline.foundation.cpe.action; import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.

  • Java GZIP压缩与解压缩代码实例

    这篇文章主要介绍了Java GZIP压缩与解压缩代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.GZIP压缩 public static byte[] compress(String str, String encoding) { if (str == null || str.length() == 0) { return null; } ByteArrayOutputStream out = new ByteArrayOutput

  • java中GZIP压缩解压类使用实例

    java中GZIP压缩解压类使用实例 当我们客户端与服务端进行数据传输时需要走流量,为了节省流量我们常常需要写一个压缩类对数据进行压缩. 实例代码: import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStr

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

    欢迎大家关注本博,同时欢迎大家评论交流,可以给个赞哦!!!   GZip是常用的无损压缩算法实现,在Linux中较为常见,像我们在Linux安装软件时,基本都是.tar.gz格式..tar.gz格式文件需要先对目录内文件进行tar压缩,然后使用GZip进行压缩.   本文针对基于磁盘的压缩和解压进行演示,演示只针对一层目录结构进行,多层目录只需递归操作进行即可.   Maven依赖   org.apache.commons: commons-compress: 1.19: 此依赖封装了很多压缩算

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

      GZip是常用的无损压缩算法实现,在Linux中较为常见,像我们在Linux安装软件时,基本都是.tar.gz格式..tar.gz格式文件需要先对目录内文件进行tar压缩,然后使用GZip进行压缩.   本文针对基于磁盘的压缩和解压进行演示,演示只针对一层目录结构进行,多层目录只需递归操作进行即可.   Maven依赖   org.apache.commons: commons-compress: 1.19: 此依赖封装了很多压缩算法相关的工具类,提供的API还是相对比较底层,我们今天在它的

  • 使用java API实现zip递归压缩和解压文件夹

    一.概述 在本篇文章中,给大家介绍一下如何将文件进行zip压缩以及如何对zip包解压.所有这些都是使用Java提供的核心库java.util.zip来实现的. 二.压缩文件 首先我们来学习一个简单的例子-压缩单个文件.将一个名为test1.txt的文件压缩到一个名为Compressed.zip的zip文件中. public class ZipFile { public static void main(String[] args) throws IOException { //输出压缩包 Fil

  • C#中对字符串进行压缩和解压的实现

    目录 利用GZip和Brotli压缩方法的优势,减少字符串数据的大小,提高.NET核心应用程序的性能. 在Visual Studio 2022中创建一个控制台应用程序项目 安装BenchmarkDotNet NuGet包 C#中的System.IO.Compression命名空间 在C#中使用GZip对数据进行压缩和解压 运行GZip压缩算法 在C#中使用Brotli对数据进行压缩和解压 运行Brotli压缩算法 用GZip和Brotli进行异步压缩和解压 在C#中用GZip和Brotli进行压

  • 基于pako.js实现gzip的压缩和解压功能示例

    本文实例讲述了基于pako.js实现gzip的压缩和解压功能.分享给大家供大家参考,具体如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>pako.js实现gzip的压缩和解压</title> </head> <body> <script type="text

  • asp.NET中实现文件的压缩和解压(3种方式)

    在.NET可以通过多种方式实现zip的压缩和解压:1.使用System.IO.Packaging:2.使用第三方类库:3.通过 System.IO.Compression 命名空间中新增的ZipArchive.ZipFile等类实现. 一.使用System.IO.Packaging压缩和解压 Package为一个抽象类,可用于将对象组织到定义的物理格式的单个实体中,从而实现可移植性与高效访问.ZIP 文件是Package的主物理格式. 其他Package实现可以使用其他物理格式(如 XML 文档

  • zlib库压缩和解压字符串STL string的实例详解

    zlib库压缩和解压字符串STL string的实例详解 场景 1.一般在使用文本json传输数据, 数据量特别大时,传输的过程就特别耗时, 因为带宽或者socket的缓存是有限制的, 数据量越大, 传输时间就越长. 网站一般使用gzip来压缩成二进制. 说明 1.zlib库可以实现gzip和zip方式的压缩, 这里只介绍zip方式的二进制压缩, 压缩比还是比较可观的, 一般写客户端程序已足够. 2.修改了一下zpipe.c的实现, 其实就是把读文件改为读字符串, 写文件改为写字符串即可. 例子

  • Swift实现文件压缩和解压示例代码

    项目中有时候需要文件下载解压,项目中选择了ZipArchive,实际使用也比较简单,直接调用解压和压缩方法即可. 压缩 @IBAction func zipAction(_ sender: UIButton) { let imageDataPath = Bundle.main.bundleURL.appendingPathComponent("FlyElephant").path zipPath = tempZipPath() let success = SSZipArchive.cr

  • Python实现文件压缩和解压的示例代码

    大家可能都熟悉.zip格式的文件.它可以把多个文件,压缩成一个文件.这在网络上传输时很有用,而且节省硬盘空间. 接下来,我们使用Python实现压缩和解压. 读取ZIP文件信息 要读取ZIP文件的内容,首先必须创建一个ZipFile对象.ZipFile对象在概念上与File对象相似. 要创建一个 ZipFile 对象,就调用 zipfile.ZipFile()函数,向它传入一个字符串,表示.zip 文件的文件名. 请注意,zipfile 是 Python 模块的名称,ZipFile()是函数的名

  • golang中tar压缩和解压文件详情

    目录 1.压缩并输出tar.gz文档 2.tar解压缩 查看官方文档,官方自带的演示: // 官方演示 package main import ( "archive/tar" "bytes" "fmt" "io" "log" "os" ) func main() { // 将若干文件写入压缩文档 // 这边源文件是直接写在代码里哈,然后也没有输出一个文档 // 后面会演示源文件进行压缩,

随机推荐