温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java中使用GZi如何实现磁盘压缩和解压

发布时间:2020-11-07 16:49:26 来源:亿速云 阅读:280 作者:Leah 栏目:开发技术

这期内容当中小编将会给大家带来有关Java中使用GZi如何实现磁盘压缩和解压,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

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.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;
 BufferedOutputStream 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);
  // 采用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;
 }

}

&#8195;&#8195;工具类测试

&#8195;&#8195;在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");
 }

}

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

总结

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

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

上述就是小编为大家分享的Java中使用GZi如何实现磁盘压缩和解压了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI