广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java 如何实现解压缩文件和文件夹
  • 844
分享到

Java 如何实现解压缩文件和文件夹

2024-04-02 19:04:59 844人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录一 前言 二 压缩文件 2.1 压缩多个文件 2.2 压缩文件或文件树 2.3 借助文件访问器压缩 三 解压文件 四 总结 一 前言 项目开发中,总会遇到解压缩文件的时候。比如

一 前言

项目开发中,总会遇到解压缩文件的时候。比如,用户下载多个文件时,服务端可以将多个文件压缩成一个文件(例如xx.zip或xx.rar)。用户上传资料时,允许上传压缩文件,服务端进行解压读取每一个文件。

基于通用性,以下介绍几种解压缩文件的方式,包装成工具类,供平时开发使用。

二 压缩文件

压缩文件,顾名思义,即把一个或多个文件压缩成一个文件。压缩也有2种形式,一种是将所有文件压缩到同一目录下,此种方式要注意文件重名覆盖的问题。另一种是按原有文件树结构进行压缩,即压缩后的文件树结构保持不变。

压缩文件操作,会使用到一个类,即ZipOutputStream。

2.1 压缩多个文件

此方法将所有文件压缩到同一个目录下。方法传入多个文件列表,和一个最终压缩到的文件路径名。


  
  public static void zipMultipleFiles(String zipFileName, File... files) throws ioException {
    ZipOutputStream zipOutputStream = null;
    try {
      // 输出流
      zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
      // 遍历每一个文件,进行输出
      for (File file : files) {
        zipOutputStream.putNextEntry(new ZipEntry(file.getName()));
        FileInputStream fileInputStream = new FileInputStream(file);
        int readLen;
        byte[] buffer = new byte[1024];
        while ((readLen = fileInputStream.read(buffer)) != -1) {
          zipOutputStream.write(buffer, 0, readLen);
        }
        // 关闭流
        fileInputStream.close();
        zipOutputStream.closeEntry();
      }
    } finally {
      if (null != zipOutputStream) {
        try {
          zipOutputStream.close();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }
  }

测试,将D盘下的infp.txt和infp1.txt文件压缩到D盘下,压缩文件名为my.zip。


  public static void main(String[] args) throws Exception {
    zipMultipleFiles("D:/my.zip", new File("D:/infp.txt"), new File("D:/infp1.txt"));
  }

2.2 压缩文件或文件树

此方法将文件夹下的所有文件按原有的树形结构压缩到文件中,也支持压缩单个文件。原理也简单,无非就是递归遍历文件树中的每一个文件,进行压缩。有个注意的点每一个文件的写入路径是基于压缩文件位置的相对路径。


package com.nobody.zip;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

public class ZipUtils {

  
  public static void zipFileTree(File sourceFile, String fORMat) throws IOException {
    ZipOutputStream zipOutputStream = null;
    try {
      String zipFileName;
      if (sourceFile.isDirectory()) { // 目录
        zipFileName = sourceFile.getParent() + File.separator + sourceFile.getName() + "."
            + format;
      } else { // 单个文件
        zipFileName = sourceFile.getParent()
            + sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf("."))
            + "." + format;
      }
      // 压缩输出流
      zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
      zip(sourceFile, zipOutputStream, "");
    } finally {
      if (null != zipOutputStream) {
        // 关闭流
        try {
          zipOutputStream.close();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }
  }

  
  private static void zip(File file, ZipOutputStream zipOutputStream, String relativePath)
      throws IOException {

    FileInputStream fileInputStream = null;
    try {
      if (file.isDirectory()) { // 当前为文件夹
        // 当前文件夹下的所有文件
        File[] list = file.listFiles();
        if (null != list) {
          // 计算当前的相对路径
          relativePath += (relativePath.length() == 0 ? "" : "/") + file.getName();
          // 递归压缩每个文件
          for (File f : list) {
            zip(f, zipOutputStream, relativePath);
          }
        }
      } else { // 压缩文件
        // 计算文件的相对路径
        relativePath += (relativePath.length() == 0 ? "" : "/") + file.getName();
        // 写入单个文件
        zipOutputStream.putNextEntry(new ZipEntry(relativePath));
        fileInputStream = new FileInputStream(file);
        int readLen;
        byte[] buffer = new byte[1024];
        while ((readLen = fileInputStream.read(buffer)) != -1) {
          zipOutputStream.write(buffer, 0, readLen);
        }
        zipOutputStream.closeEntry();
      }
    } finally {
      // 关闭流
      if (fileInputStream != null) {
        try {
          fileInputStream.close();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }
  }

  public static void main(String[] args) throws Exception {
    String path = "D:/test";
    String format = "zip";
    zipFileTree(new File(path), format);
  }
}

上例将test目录下的所有文件压缩到同一目录下的test.zip文件中。

2.3 借助文件访问器压缩

还有一种更简单的方式,我们不自己写递归遍历。借助Java原生类,SimpleFileVisitor,它提供了几个访问文件的方法,其中有个方法visitFile,对于文件树中的每一个文件(文件夹除外),都会调用这个方法。我们只要写一个类继承SimpleFileVisitor,然后重写visitFile方法,实现将每一个文件写入到压缩文件中即可。

当然,除了visitFile方法,它里面还有preVisitDirectory,postVisitDirectory,visitFileFailed等方法,通过方法名大家也猜出什么意思了。


package com.nobody.zip;

import java.io.FileOutputStream;
import java.io.IOException;
import java.NIO.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;


public class ZipFileTree extends SimpleFileVisitor<Path> {

  // zip输出流
  private ZipOutputStream zipOutputStream;
  // 源目录
  private Path sourcePath;

  public ZipFileTree() {}

  
  public void zipFile(String sourceDir) throws IOException {
    try {
      // 压缩后的文件和源目录在同一目录下
      String zipFileName = sourceDir + ".zip";
      this.zipOutputStream = new ZipOutputStream(new FileOutputStream(zipFileName));
      this.sourcePath = Paths.get(sourceDir);

      // 开始遍历文件树
      Files.walkFileTree(sourcePath, this);
    } finally {
      // 关闭流
      if (null != zipOutputStream) {
        zipOutputStream.close();
      }
    }
  }

  // 遍历到的每一个文件都会执行此方法
  @Override
  public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException {
    // 取相对路径
    Path targetFile = sourcePath.relativize(file);
    // 写入单个文件
    zipOutputStream.putNextEntry(new ZipEntry(targetFile.toString()));
    byte[] bytes = Files.readAllBytes(file);
    zipOutputStream.write(bytes, 0, bytes.length);
    zipOutputStream.closeEntry();
    // 继续遍历
    return FileVisitResult.CONTINUE;
  }

  // 遍历每一个目录时都会调用的方法
  @Override
  public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
      throws IOException {
    return super.preVisitDirectory(dir, attrs);
  }

  // 遍历完一个目录下的所有文件后,再调用这个目录的方法
  @Override
  public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
    return super.postVisitDirectory(dir, exc);
  }

  // 遍历文件失败后调用的方法
  @Override
  public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
    return super.visitFileFailed(file, exc);
  }

  public static void main(String[] args) throws IOException {
    // 需要压缩源目录
    String sourceDir = "D:/test";
    // 压缩
    new ZipFileTree().zipFile(sourceDir);
  }
}

三 解压文件

解压压缩包,借助ZipInputStream类,可以读取到压缩包中的每一个文件,然后根据读取到的文件属性,写入到相应路径下即可。对于解压压缩包中是文件树的结构,每读取到一个文件后,如果是多层路径下的文件,需要先创建父目录,再写入文件流。


package com.nobody.zip;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;


public class ZipUtils {

  
  public static void unzip(String zipFilePath, String desDirectory) throws Exception {

    File desDir = new File(desDirectory);
    if (!desDir.exists()) {
      boolean mkdirSuccess = desDir.mkdir();
      if (!mkdirSuccess) {
        throw new Exception("创建解压目标文件夹失败");
      }
    }
    // 读入流
    ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath));
    // 遍历每一个文件
    ZipEntry zipEntry = zipInputStream.getNextEntry();
    while (zipEntry != null) {
      if (zipEntry.isDirectory()) { // 文件夹
        String unzipFilePath = desDirectory + File.separator + zipEntry.getName();
        // 直接创建
        mkdir(new File(unzipFilePath));
      } else { // 文件
        String unzipFilePath = desDirectory + File.separator + zipEntry.getName();
        File file = new File(unzipFilePath);
        // 创建父目录
        mkdir(file.getParentFile());
        // 写出文件流
        BufferedOutputStream bufferedOutputStream =
            new BufferedOutputStream(new FileOutputStream(unzipFilePath));
        byte[] bytes = new byte[1024];
        int readLen;
        while ((readLen = zipInputStream.read(bytes)) != -1) {
          bufferedOutputStream.write(bytes, 0, readLen);
        }
        bufferedOutputStream.close();
      }
      zipInputStream.closeEntry();
      zipEntry = zipInputStream.getNextEntry();
    }
    zipInputStream.close();
  }

  // 如果父目录不存在则创建
  private static void mkdir(File file) {
    if (null == file || file.exists()) {
      return;
    }
    mkdir(file.getParentFile());
    file.mkdir();
  }

  public static void main(String[] args) throws Exception {
    String zipFilePath = "D:/test.zip";
    String desDirectory = "D:/a";
    unzip(zipFilePath, desDirectory);
  }
}

四 总结

在解压缩文件过程中,主要是对流的读取操作,注意进行异常处理,以及关闭流。
WEB应用中,通过接口可以实现文件上传下载,对应的我们只要把压缩后的文件,写入到response.getOutputStream()输出流即可。
解压缩文件时,注意空文件夹的处理。

此演示项目已上传到GitHub,如有需要可自行下载,欢迎 Star 。 https://github.com/Luciochn/common-utils

以上就是Java 如何实现解压缩文件和文件夹的详细内容,更多关于Java 解压缩文件和文件夹的资料请关注编程网其它相关文章!

--结束END--

本文标题: Java 如何实现解压缩文件和文件夹

本文链接: https://www.lsjlt.com/news/121408.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java 如何实现解压缩文件和文件夹
    目录一 前言 二 压缩文件 2.1 压缩多个文件 2.2 压缩文件或文件树 2.3 借助文件访问器压缩 三 解压文件 四 总结 一 前言 项目开发中,总会遇到解压缩文件的时候。比如...
    99+
    2022-11-11
  • java如何解压与压缩文件夹
    这篇文章将为大家详细讲解有关java如何解压与压缩文件夹,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。注意:JDK7支持设置编码设置编码格式 zipFile,zipInputStream,zipOutpu...
    99+
    2023-05-31
    java
  • Android如何实现压缩和解压缩文件
    废话不多说了,直接给大家贴java代码了,具体代码如下所示: Java代码 package com.maidong.utils; import java.io.Buffe...
    99+
    2022-06-06
    压缩 解压 Android
  • Java如何实现文件压缩为zip和解压zip压缩包
    本篇内容介绍了“Java如何实现文件压缩为zip和解压zip压缩包”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!压缩成.zip代码如下:pu...
    99+
    2023-07-02
  • Java实现文件压缩为zip和解压zip压缩包
    目录压缩成.zip解压.zip压缩成.zip 代码如下: public static void toZip(String srcDir, OutputStream out) th...
    99+
    2022-11-13
  • 【Java 基础篇】Java Zip压缩:简化文件和文件夹的压缩操作
    文章目录 导言一、Zip压缩简介二、压缩文件1. 创建压缩文件2. 压缩多个文件3. 压缩文件夹 三、解压缩文件1、解压缩文件 总结 导言 在Java开发中,经常会遇到需要对文件和文件夹进行压缩和解压缩的需求。J...
    99+
    2023-08-17
    java python php
  • ubuntu如何压缩文件夹
    在Ubuntu中,可以使用以下命令压缩文件夹:1. 使用tar命令:```tar -zcvf archive.tar.gz fold...
    99+
    2023-08-29
    ubuntu
  • 【linux】tar指令压缩解压缩文件夹、文件命令详解
    1. tar常用命令: 压缩当前目录下文件夹/文件test到test.tar.gz: tar -zcvf test.tar.gz test 解压缩当前目录下的file.tar.gz到file: tar...
    99+
    2023-08-31
    linux 服务器 运维 压缩tar
  • 如何在Linux中zip压缩文件和文件夹
    这期内容当中小编将会给大家带来有关如何在Linux中zip压缩文件和文件夹,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。zip 是***的归档文件格式之一。使用 zip,你可以将多个文件压缩到一个文件中。...
    99+
    2023-06-16
  • php压缩文件时文件夹乱码如何解决
    本篇内容介绍了“php压缩文件时文件夹乱码如何解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!php压缩文件时文件夹乱码的解决办法:1、修...
    99+
    2023-07-04
  • Python怎么批量解压和压缩文件夹
    这篇文章主要介绍“Python怎么批量解压和压缩文件夹”,在日常操作中,相信很多人在Python怎么批量解压和压缩文件夹问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Python怎么批量解压和压缩文件夹”的疑...
    99+
    2023-06-29
  • Java压缩与解压缩ZIP文件
    文章目录 前言Java解压缩文件压缩和解压缩ZIP文件检验应用总结 前言 在现代计算机上,数据传输和存储越来越依赖于文件压缩技术。当我们需要发送大量数据时,压缩文件可以大大减少传输时间...
    99+
    2023-09-11
    java zip 压缩文件 解压缩文件 ZipOutputStream
  • vbs中怎么实现压缩文件夹
    今天就跟大家聊聊有关vbs中怎么实现压缩文件夹,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。strComputer = "." Set&nbs...
    99+
    2023-06-08
  • java工具类 - 实现文件压缩zip及解压缩
    对hutool工具类进行的封装 依赖 cn.hutool hutool-all 5.8.15 ...
    99+
    2023-10-28
    java
  • 里有Java如何实现压缩与解压zip文件
    里有Java如何实现压缩与解压zip文件?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java解压缩zip - 多个文件(包括文件夹),对多个文件和文件夹进行压...
    99+
    2023-05-31
    java ava zip
  • linux压缩文件和文件解压缩命令介绍
    目录常见压缩格式:gz .bz2 .xz .zip常用归档调用压缩压缩比及压缩速度:gzip命令:压缩查看压缩文件:gunzip命令:解压bzip2:命令压缩查看压缩文件bunzip2命令:解压xz命令:压缩查看压缩文件...
    99+
    2022-06-04
    linux压缩文件 linux文件解压
  • Linux如何压缩某个文件夹
    小编给大家分享一下Linux如何压缩某个文件夹,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!Linux 压缩某个文件夹的实现方法tar -zcvf /home/xahot.tar.gz /xahot tar -zcvf 打...
    99+
    2023-06-09
  • Python实现批量压缩文件/文件夹zipfile的使用
    目录【Python压缩文件夹】导入“zipfile”模块【python压缩文件】导入“zipfile”模块补充zipfile是python里用来做zip格式编码的压缩和解压缩的,由于...
    99+
    2022-11-12
  • java实现哈夫曼文件解压缩
    本文实例为大家分享了java实现哈夫曼文件解压缩的具体代码,供大家参考,具体内容如下 1、哈夫曼压缩对已经经过压缩处理的文件压缩率比较低,比如ppt和视频。 2、这个程序主要涉及到集...
    99+
    2022-11-12
  • nodejs原生怎么实现压缩文件夹
    随着当今互联网技术和业务的不断发展,文件传输和存储成为了不可或缺的一部分。我们经常需要将一些大小比较大的文件或文件夹压缩成一个压缩包,以便于传输或存储。而开发人员要如何实现文件夹的压缩呢?本文将介绍如何使用Node.js来原生实现文件夹的压...
    99+
    2023-05-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作