【Java-压缩文件的加/解压】一文了解加/解压

news2024/11/7 5:24:12

文章目录

    • 概要
    • 技术详解
    • Java代码实例
    • 小结

概要

7z、zip、gz、tar、rar以及tar.gz是不同的文件压缩和归档格式,它们各自具有独特的特点和用途。本篇文章通过Java对文件进行加密压缩/解压、目录及多文件归档等进行阐述。

技术详解

  1. 7z:
  • 定义:7z是一种新的压缩格式,由7-Zip软件发布,采用GNU LGPL协议。
  • 特点:拥有目前最高的压缩比,支持Unicode文件名,具有公开的结构编辑功能和强大的AES-256加密,可更改和配置压缩算法,最高支持16EB(16000000000GB)的文件压缩。
  • 使用场景:适用于需要高压缩比的场景,如存储大量数据或进行网络传输时。
  1. zip:
  • 定义:zip是一种广泛使用的压缩文件格式,由菲尔·卡茨(Phil Katz)于1989年创建。
  • 特点:采用DEFLATE等压缩算法,文件体积小,支持多文件合并,具有目录结构,便于传输和存储。但原生不支持Unicode文件名,可能导致部分文件共享困难。
  • 使用场景:适用于文件和文件夹的打包和压缩,是网络和本地存储的常用选择。
  1. gz(通常与tar结合使用形成tar.gz):
  • 定义:gz是gzip命令生成的压缩文件格式。
  • 特点:gzip是一种无损数据压缩程序,常用于UNIX和类UNIX系统中。
  • 使用场景:通常与tar命令结合使用,形成tar.gz格式,用于Linux系统中的文件打包和压缩。
  1. tar:
  • 定义:tar是一种常用的文件打包格式,在Linux和Unix系统中广泛使用。
  • 特点:可以将多个文件和目录合并成一个文件,方便存储和传输。但tar本身并不进行压缩,只是进行归档。
  • 使用场景:适用于需要将多个文件和目录组合成一个单独文件的场景。
  1. rar:
  • 定义:rar是一种文件压缩与归档的私有文件格式,由WinRAR软件发布。
  • 特点:具有较高的压缩比,支持分卷压缩、固实压缩和恢复记录功能,还提供了加密功能。但RAR是收费的。
  • 使用场景:适用于需要高压缩比和加密保护的场景。
  1. tar.gz:
  • 定义:tar.gz是tar命令打包文件后,再通过gzip命令进行压缩得到的文件格式。
  • 特点:结合了tar的打包功能和gzip的压缩功能,可以有效地减小文件大小,方便传输和存储。
  • 使用场景:广泛应用于Linux系统中的文件打包、压缩和管理等方面。

Java代码实例

  1. tar文件解压归档
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.utils.IOUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
* String outputTarFile = "output.tar";
  String[] filesToAdd = {"file1.txt", "file2.txt"}; // 要添加到 tar 文件中的文件路径
*/
public static File compressTar( String outputTarFile, String[] filesToAdd) {
     try (FileOutputStream fos = new FileOutputStream(outputTarFile);
          TarArchiveOutputStream taos = new TarArchiveOutputStream(fos)) {
         for (String filePath : filesToAdd) {
             File file = new File(filePath);
             TarArchiveEntry entry = new TarArchiveEntry(file, filePath);
             taos.putArchiveEntry(entry);
             try (InputStream fis = new FileInputStream(file)) {
                 IOUtils.copy(fis, taos);
             }
             taos.closeArchiveEntry();
         }
         System.out.println("Tar 文件创建成功: " + outputTarFile);
     } catch (IOException e) {
         e.printStackTrace();
     }
 }

/**
解压tar文件,original 源文件,outPath 解压路径
*/
public static List<File> unCompressTar(File original, String outPath) throws IOException {
        List<File> files = new ArrayList<>();
        try (TarArchiveInputStream tais =
                     new TarArchiveInputStream(new FileInputStream(original), "UTF-8")) {
            TarArchiveEntry tarArchiveEntry = null;
            while ((tarArchiveEntry = tais.getNextTarEntry()) != null) {
                String name = tarArchiveEntry.getName();
                File tarFile = new File(outPath, name);
                if (tarArchiveEntry.isDirectory()) {
                    tarFile.mkdirs();
                    continue;
                }
                if (!tarFile.getParentFile().exists()) {
                    tarFile.getParentFile().mkdirs();
                }
                try (BufferedOutputStream bos =
                             new BufferedOutputStream(new FileOutputStream(tarFile))) {
                    int read = -1;
                    byte[] buffer = new byte[BUFFER_SIZE];
                    while ((read = tais.read(buffer)) != -1) {
                        bos.write(buffer, 0, read);
                    }
                    bos.flush();
                    bos.close();
                }
            }
            getFiles(new File(outPath), files);
        }

        return files;
    }
  1. tar.gz代码实例
    实际就是先对gzip处理,然后对tar解压。
public static List<File> unCompressArchiveGz(File archive, String outPath) throws IOException {
    String fileName = archive.getName();
    try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(archive))) {
        try (BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream(outPath + File.separator + fileName))) {
            GzipCompressorInputStream gcis = new GzipCompressorInputStream(bis);
            byte[] buffer = new byte[BUFFER_SIZE];
            int read = -1;
            while ((read = gcis.read(buffer)) != -1) {
                bos.write(buffer, 0, read);
            }
            bos.flush();
            bos.close();
        }
    }
    //调用上述解压tar的方法
    return unCompressTar(outPath + File.separator + fileName);
}
  1. rar 压缩与解压
  • rar4
    这里使用的是com.github.junrar,但是其最新版本只支持rar1-rar4,不支持最新的rar5算法
    github例子:官方例子
<dependency>
  <groupId>com.github.junrar</groupId>
  <artifactId>junrar</artifactId>
  <version>{version}</version>
</dependency>

//优雅的解压文件
Junrar.extract("/tmp/foo.rar", "/tmp", "password");
//无密码
Junrar.extract("/tmp/foo.rar", "/tmp");
  • 针对rar5 的支持需要使用sevenzipjbinding
    参考博客代码:https://blog.csdn.net/qq_41841482/article/details/124864484
    但是上述博客没有讲针对加密的rar5文件的解压处理,需要参考官方的demo用例,进一步的改写。
    官方测试用例:sevenzipjbinding用例,就是在打开文件时需要加入密码即可。
  1. ZIP解压
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ExtraDataRecord;
import net.lingala.zip4j.model.FileHeader;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.CompressionLevel;
import net.lingala.zip4j.model.enums.CompressionMethod;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import net.lingala.zip4j.util.InternalZipConstants;

public static List<File> unzip(File zipFile, String dest, String password) throws ZipException, IOException {
    ZipFile zFile = new ZipFile(zipFile);
    //设置GBK解决文件名和中文路径乱码的问题
    zFile.setCharset(InternalZipConstants.CHARSET_UTF_8);
    List<FileHeader> headers = zFile.getFileHeaders();
    for (FileHeader fileHeader : headers) {
        if (!fileHeader.isDirectory()) {
            String fileName = fileHeader.getFileName();
            if (isMessy(fileName)) {
                zFile = new ZipFile(zipFile);
                zFile.setCharset(Charset.forName(UTF8));
                break;
            }
        }
    }
    File dstFile = null;
    if (dest.endsWith(File.separator) == false) {
        dest = dest + File.separator;
    }
    dstFile = new File(dest);
    if (dstFile.isDirectory() && !dstFile.exists()) {
        dstFile.mkdirs();
    }

    if (zFile.isEncrypted()) {
        if (null == password || password.length() == 0) {
            return new ArrayList<>();
        }
        zFile.setPassword(getPassword(password));
    }
//        zFile.extractAll(dstFile.getAbsolutePath());
    List<FileHeader> headerList = zFile.getFileHeaders();
    List<File> extractedFileList = new ArrayList<File>();
    for (FileHeader fileHeader : headerList) {
        if (!fileHeader.isDirectory()) {
            String fileNameFromExtraData = getFileNameFromExtraData(fileHeader);
            zFile.extractFile(fileHeader, dest, fileNameFromExtraData);
            File newFile = new File(dest + fileNameFromExtraData);
            extractedFileList.add(newFile);
        }
    }

    return extractedFileList;
}
  1. 7z的解压处理
/**
* 解压缩7z文件
*
* @param file       压缩包文件
* @param targetPath 目标文件夹
*/
public static List<File> decompress7Z(File file, String targetPath, String password) throws Exception {
   List<File> files = new ArrayList<>();
   SevenZFile sevenZFile = null;
   OutputStream outputStream = null;
   try {
       if (StringUtils.isNoneBlank(password)) {
           sevenZFile = new SevenZFile(file, password.getBytes());
           //sevenZFile = new SevenZFile(file,getPasswordBytes(password));
       } else {
           sevenZFile = new SevenZFile(file);
       }
       // 创建输出目录
       File targetDir = new File(targetPath);
       targetDir.mkdirs();
       SevenZArchiveEntry entry;

       while ((entry = sevenZFile.getNextEntry()) != null) {
           if (entry.isDirectory()) {
               new File(targetPath + File.separator + entry.getName()).mkdirs();
           } else {
               new File(targetPath + File.separator + entry.getName()).getParentFile().mkdirs();
               outputStream = new FileOutputStream(new File(targetPath + File.separator + entry.getName()));
               int len = 0;
               byte[] b = new byte[2048];
               while ((len = sevenZFile.read(b)) != -1) {
                   outputStream.write(b, 0, len);
               }
               outputStream.flush();
               outputStream.close();
           }
       }
       getFiles(targetDir, files);
   } finally {
       try {
           if (sevenZFile != null) {
               sevenZFile.close();
           }
           if (outputStream != null) {
               outputStream.close();
           }
       } catch (IOException e) {
           e.printStackTrace();
       }
   }
   return files;
}

小结

格式压缩效率压缩速度解压速度兼容性安全性特殊功能
7z较慢较快较好(需7-Zip支持)强(AES-256加密)高压缩比,支持分卷压缩
zip广(跨平台支持)中(支持加密,但密码可能泄露)支持多文件合并,目录结构
gz (gzip)中(常与tar结合使用)好(Linux/Unix系统广泛支持)无(仅压缩,需与tar结合形成tar.gz)
tar无(仅打包,不压缩)快(打包速度)快(解压速度)好(Linux/Unix系统广泛支持)文件打包,便于存储和传输
rar较好(需WinRAR等支持)强(AES加密)支持分卷压缩,固实压缩,恢复记录
tar.gz高(tar打包后gzip压缩)好(Linux/Unix系统广泛支持)打包和压缩结合,适用于Linux系统管理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2234789.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

25.停车场管理系统(基于web的Java项目)

目录 1.系统的受众说明 2.相关技术与方法 3.系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 经济可行性 3.1.3 操作可行性 3.2 需求分析 3.2.1 系统功能描述 3.2.2 用例图分析 4. 系统设计 4.1 系统类分析 5. 系统详细设计与实现 5.1 用户登录 5.2 系统信…

【含开题报告+文档+源码】基于SpringBoot+Vue智能居民健康检测系统设计与实现

开题报告 随着社会发展和人民生活水平的提高&#xff0c;人们对健康生活的要求越来越高。而广大居民由于条件限制&#xff0c;存在着健康管理服务不足的问题。本文基于JavaWeb技术&#xff0c;设计并实现了一种居民健康检测系统。首先&#xff0c;本文对该平台的需求进行了分析…

SCNU习题 总结与复习

1. P1:构建最大二叉树 【分治】 重点 构树函数需要注意的点&#xff1b; 前序遍历需要注意&#xff0c;本题的输出有点特点。若一个结点无左子&#xff0c;无右子就不再下去遍历&#xff1b; 其他情况都要下去遍历&#xff1b; 2. P2 寻找多数【分治】 没啥&#xff0c;注意…

ssm060基于SSM的高校共享单车管理系统的设计与实现+vue(论文+源码)_kaic

设计题目&#xff1a;高校共享单车管理系统的设计与实现 摘 要 网络技术和计算机技术发展至今&#xff0c;已经拥有了深厚的理论基础&#xff0c;并在现实中进行了充分运用&#xff0c;尤其是基于计算机运行的软件更是受到各界的关注。加上现在人们已经步入信息时代&#xff0…

【算法】(Python)贪心算法

贪心算法&#xff1a; 又称贪婪算法&#xff0c;greedy algorithm。贪心地追求局部最优解&#xff0c;即每一步当前状态下最优选择。试图通过各局部最优解达到最终全局最优解。但不从整体最优上考虑&#xff0c;不一定全局最优解。步骤&#xff1a;从初始状态拆分成一步一步的…

记一次微信云托管搭建Redis服务

背景 最近在做一个微信小程序&#xff0c;规划服务全部部署在云托管上面&#xff0c;本次使用了对象存储、mysql、java服务、Redis服务&#xff08;pc端用的&#xff09;。 由于对部署Redis不理解&#xff0c;查看了官方文档&#xff0c;首先看到的是这个架构图&#xff0c;看…

基于SSM的校园美食交流系统【附源码】

基于SSM的校园美食交流系统 效果如下&#xff1a; 管理员主页面 用户主页面 美食信息页面 美食资讯页面 修改密码页面 论坛中心页面 研究背景 随着高校信息化建设的不断推进&#xff0c;校园生活日益丰富多样&#xff0c;学生对于美食的需求与探索也愈发旺盛。然而&#xff…

Linux—进程学习-01

目录 Linux—进程学习—11.冯诺依曼体系结构2.操作系统2.1操作系统的概念2.2操作系统的目的2.3如何理解管理2.4计算机软硬件体系的理解2.5系统调用和库函数的概念 3.进程3.1进程是什么3.2管理进程3.2.1描述进程-PCB3.2.2组织进程3.2.3总结 3.3查看进程 4.与进程有关的系统调用 …

【电子通识】白皮书、应用手册、用户指南、快速入门指南一般的定义是什么?

一般大厂家的器件或模块,除了给数据表以外,还提供应用手册、技术说明、白皮书等各种文档资料。 如下图所示为ST25 NFC/RFID标签和读卡器的文件资料:其中就有技术说明、白皮书、应用手册等。 如下所示为TI INA228技术文档相关资料: 也有应用手册、用户指南、技术文章…

python opencv灰度变换

灰度变换 灰度变换和二值化的区别&#xff1a; 灰度变换是调整调整图像的灰度动态范围或图像对比度二值化是将图像的每个像素点调至0或255&#xff0c;只呈现白色或黑色 1.灰度化处理 图片的灰度化&#xff1a;将一个像素点的三个颜色变量相等&#xff0c;RGB&#xff0c;此…

toolkit二次开发学习之程序集(ProAsmcomp)和装配体组件路径对象(ProAsmcomppath)

程序集ProAsmcomp可以理解为装配体组件对象。 对象ProAssembly是ProSolid的一个实例&#xff0c;并共享相同的声明。因此&#xff0c;ProAssembly对象可以作为适用于装配体的任何ProSolid和ProMdl函数的输入。特别是&#xff0c;因为你可以使用函数ProSolidFeatVisit()来遍历特…

WPF中如何简单的使用CommunityToolkit.Mvvm创建一个项目并进行 增删改查

目录 开始前准备的数据库dbblog如下&#xff1a; 第一步&#xff1a;创建项目后下载四个NuGet程序包 第二步&#xff1a;删除原本的MainWindow.XAML文件 并创建如下的目录结构 然后在View文件夹下面创建Login.XAML和Main.XAML 并且在App.XAML中将启动项改为Login.X…

【51蛋骗鸡一共八个灯 按顺序依次12。34。56。78。两个灯同时亮灭的代码】2022-1-19

缘由proteus流水灯-嵌入式-CSDN问答 仿真51单片机流水灯代码-编程语言-CSDN问答 protues仿真单片机控制led流水灯-嵌入式-CSDN问答 #include<reg52.h>//头文件 void main() //主函数 {unsigned char y23;unsigned int ys0;while(1){if(!ys){P0y2;if(!(y2*4))y23…

数据结构:跳表实现(C++)

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》《网络》 《redis学习笔记》 文章目录 前言跳表跳表的优化思路skiplist&#xff0c;平衡搜索树&#xff0c;哈希表的对比 实现思路SkiplistNodesearch 搜索add 增加earse 删除 整体…

ssm基于Web的汽车客运订票系统的设计与实现+vue

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码看文章最下面 需要定制看文章最下面 目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容…

SSM中maven

一&#xff1a;maven的分模块开发 maven分模块就是在多人操作一个项目时将maven模块导入依赖&#xff0c;注意仓库里面没有资源坐标&#xff0c;需要使用install操作下载。 二&#xff1a;maven的依赖管理 pom文件中直接写的依赖叫做直接依赖&#xff0c;直接依赖中用到的依…

如何找到养生生活视频素材?推荐几个优秀网站

今天&#xff0c;我们来聊一个实用的话题&#xff0c;那就是如何找到优质的养生视频素材。作为自媒体创作者&#xff0c;高质量的视频素材对内容制作至关重要。不论你是刚入行的新手&#xff0c;还是已经积累了一定粉丝的大V&#xff0c;找到合适的养生视频素材都能帮助你更好地…

vscode的一些使用心得

问题1&#xff1a;/home目录空间有限 连接wsl或者remote的时候&#xff0c;会在另一端下载一个.vscode-server&#xff0c;vscode的插件都会安装进去&#xff0c;导致空间增加很多&#xff0c;可以选择更换这个文件的位置 参考&#xff1a;https://blog.csdn.net/weixin_4389…

画动态爱心(Python-matplotlib)

介绍 氵而已 由于用的是 AI&#xff0c;注释得非常清楚&#xff0c;自己改改也可以用 代码 # -*- coding: utf-8 -*- # Environment PyCharm # File_name 尝试1 |User Pfolg # 2024/11/05 22:45 import numpy as np import matplotlib.pyplot as plt import matplot…

13-鸿蒙开发中的综合实战:华为登录界面

大家好&#xff0c;欢迎来到鸿蒙开发系列教程&#xff01;今天&#xff0c;我们将通过一个综合实战项目来实现一个华为登录界面。这个项目将涵盖输入框组件、按钮组件、文本组件和布局容器的使用&#xff0c;帮助你更好地理解和应用这些组件。无论你是初学者还是有一定经验的开…