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

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

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

一 压缩文件

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

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

1.1 压缩多个文件

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

/** * 压缩多个文件,压缩后的所有文件在同一目录下 * * @param zipFileName 压缩后的文件名 * @param files 需要压缩的文件列表 * @throws IOException IO异常 */ 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")); } 1.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 { /** * 压缩文件或文件夹(包括所有子目录文件) * * @param sourceFile 源文件 * @param format 格式(zip或rar) * @throws IOException 异常信息 */ 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(); } } } } /** * 递归压缩文件 * * @param file 当前文件 * @param zipOutputStream 压缩输出流 * @param relativePath 相对路径 * @throws IOException IO异常 */ 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 ? "" : "http://www.likecs.com/") + file.getName(); // 递归压缩每个文件 for (File f : list) { zip(f, zipOutputStream, relativePath); } } } else { // 压缩文件 // 计算文件的相对路径 relativePath += (relativePath.length() == 0 ? "" : "http://www.likecs.com/") + 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文件中。

1.3 借助文件访问器压缩

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssdwf.html