java压缩zip文件夹错误_Java将文件或者文件夹压缩成zip(修复文件夹中存在多个文件报Stream Closed错误问题)...

项目场景:

Java将文件或者文件夹压缩成zip(修复文件夹中存在多个文件报Stream Closed错误问题)

问题描述:

最近的项目需要将多级文件夹压缩成zip,网上找了几个工具类,都会报错,所以找个其中这一个文章中的工具类改进了后,已解决文件夹中存在多个文件报Stream Closed错误问题。

ps:java新手,不知道这样改有没有问题,希望大神们帮忙研究下

原工具类文章链接:

原因分析:

zos.close();

改为在调用最外层try-catch-finally里只关闭一次,避免闭关多次关闭后,再次执行报错。

原有的逻辑没有删除,改为注释掉了

解决方案:

package utils;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.ArrayList;

import java.util.List;

import java.util.zip.ZipEntry;

import java.util.zip.ZipOutputStream;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

// 压缩zip方法

public class ZipUtil {

private static final int BUFFER_SIZE = 2 * 1024;

private static Logger logger = LoggerFactory.getLogger(ZipUtil.class);

/**

* 压缩成ZIP 方法1

*

* @param srcDir

* 压缩文件夹路径

* @param out

* 压缩文件输出流

* @param KeepDirStructure

* 是否保留原来的目录结构,true:保留目录结构;

* false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)

* @throws RuntimeException

* 压缩失败会抛出运行时异常

*/

public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure){

long start = System.currentTimeMillis();

ZipOutputStream zos = null;

try {

zos = new ZipOutputStream(out);

File sourceFile = new File(srcDir);

compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);

long end = System.currentTimeMillis();

logger.debug("压缩完成,耗时:" + (end - start) + " ms");

} catch (Exception e) {

e.printStackTrace();

logger.error("系统异常:",e);

} finally {

//zos != null zos.close(); 并不是判断zos是否被关闭 而是这个对象是否创建成功

if (zos != null) {

try {

zos.close();

} catch (IOException e) {

e.printStackTrace();

logger.error("系统异常:",e);

}

}

}

}

/**

* 压缩成ZIP 方法2

*

* @param srcFiles

* 需要压缩的文件列表

* @param out

* 压缩文件输出流

* @throws RuntimeException

* 压缩失败会抛出运行时异常

*/

public static void toZip(List srcFiles, OutputStream out){

long start = System.currentTimeMillis();

ZipOutputStream zos = null;

try {

zos = new ZipOutputStream(out);

for (File srcFile : srcFiles) {

byte[] buf = new byte[BUFFER_SIZE];

zos.putNextEntry(new ZipEntry(srcFile.getName()));

int len;

FileInputStream in = new FileInputStream(srcFile);

while ((len = in.read(buf)) != -1) {

zos.write(buf, 0, len);

}

zos.closeEntry();

in.close();

}

long end = System.currentTimeMillis();

logger.debug("压缩完成,耗时:" + (end - start) + " ms");

} catch (Exception e) {

e.printStackTrace();

logger.error("系统异常:",e);

} finally {

if (zos != null) {

try {

zos.close();

} catch (IOException e) {

e.printStackTrace();

logger.error("系统异常:",e);

}

}

}

}

/**

* 压缩成ZIP 方法2

*

* @param srcFiles

* 需要压缩的文件列表

* @param out

* 压缩文件输出流

* @throws RuntimeException

* 压缩失败会抛出运行时异常

*/

public static void toZip(File[] srcFiles, OutputStream out){

long start = System.currentTimeMillis();

ZipOutputStream zos = null;

try {

zos = new ZipOutputStream(out);

for (File srcFile : srcFiles) {

byte[] buf = new byte[BUFFER_SIZE];

zos.putNextEntry(new ZipEntry(srcFile.getName()));

int len;

FileInputStream in = new FileInputStream(srcFile);

while ((len = in.read(buf)) != -1) {

zos.write(buf, 0, len);

}

zos.closeEntry();

in.close();

}

long end = System.currentTimeMillis();

logger.debug("压缩完成,耗时:" + (end - start) + " ms");

} catch (Exception e) {

e.printStackTrace();

logger.error("系统异常:",e);

} finally {

if (zos != null) {

try {

zos.close();

} catch (IOException e) {

e.printStackTrace();

logger.error("系统异常:",e);

}

}

}

}

/**

*

* 递归压缩方法

*

* @param sourceFile

* 源文件

*

* @param zos

* zip输出流

*

* @param name

* 压缩后的名称

*

* @param KeepDirStructure

* 是否保留原来的目录结构,true:保留目录结构;

*

* false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)

*

* @throws Exception

*

*/

//工具类有逻辑问题 已更改添加注释 便于理解

private static void compress(File sourceFile, ZipOutputStream zos, String name,

boolean KeepDirStructure) throws IOException {

byte[] buf = new byte[BUFFER_SIZE];

//异常改为向上层抛出 避免 zos.close(); 没有执行

// try {

if (sourceFile.isFile()) {

// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字

zos.putNextEntry(new ZipEntry(name));

// copy文件到zip输出流中

int len;

FileInputStream in = new FileInputStream(sourceFile);

while ((len = in.read(buf)) != -1) {

zos.write(buf, 0, len);

}

// Complete the entry

zos.closeEntry();

in.close();

} else {

File[] listFiles = sourceFile.listFiles();

if (listFiles == null || listFiles.length == 0) {

// 需要保留原来的文件结构时,需要对空文件夹进行处理

if (KeepDirStructure) {

// 空文件夹的处理

zos.putNextEntry(new ZipEntry(name + "/"));

// 没有文件,不需要文件的copy

zos.closeEntry();

}

} else {

for (File file : listFiles) {

// 判断是否需要保留原来的文件结构

if (KeepDirStructure) {

// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,

// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了

compress(file, zos, name + "/" + file.getName(), KeepDirStructure);

} else {

compress(file, zos, file.getName(), KeepDirStructure);

}

}

}

}

// }catch(Exception e){

// e.printStackTrace();

// logger.error("系统异常:",e);

// } finally {

// 递归时,不需要把zip输出流关闭,zip输出流的关闭应该是在调用完递归方法后面关闭 这里不再关闭 在最外层关闭

// if (zos != null) {

// try {

// zos.close();

// } catch (IOException e) {

// e.printStackTrace();

// logger.error("系统异常:",e);

// }

//

// }

// }

}

public static void main(String[] args) throws Exception {

/** 测试压缩方法1 */

FileOutputStream fos1 = new FileOutputStream(new File("F:/11.zip"));

ZipUtil.toZip("F:/driverDailyInspection", fos1, true);

/** 测试压缩方法2 */

//List fileList = new ArrayList<>();

//fileList.add(new File("E:/emailTemplate.html"));

//fileList.add(new File("E:/logobottom.jpg"));

//FileOutputStream fos2 = new FileOutputStream(new File("E:/mytest02.zip"));

//ZipUtil.toZip(fileList, fos2);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值