java 多级文件压缩保留层级关系

  • 前言
  • 为什么要压缩文件夹
  • 正文
  • 结果展示
  • 总结


前言

为什么要压缩文件夹

当我们要在网络上实现下载多个文件的时候不可能把文件一个一个的下载,首先不说太麻烦就算下载下来了你也不好管理,文件也没有保存原来该有的文件目录结构。
那为什么不直接传输文件夹呢,如果你这样想那你可能对文件夹这个概念有所误解,首先文件夹并不包含其内部文件或文件夹,文件夹你可以把它看成是一个目录只能让你了解到有哪些文件。这就是为什么我们直接把文件夹转换为io流时会抛出拒绝访问,假如你能操作并更改了文件夹那么就意味着目录被损坏还能知道内部有哪些文件吗,这个文件夹也就被损坏了。

正文

不说了直接上代码吧

package commontsCompress;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Compress {

	/**
	 * 
	 * @param source 源文件
	 * @param zos    zip输出流
	 * @param path   文件相对路径
	 */
	public static void compressFolder(File source, ZipOutputStream zos, String path) {
		// 判读是否为文件夹
		if (source.isFile()) { // 是文件
			try {
				// 向zip输出流添加该文件的zip实体
				zos.putNextEntry(new ZipEntry(path));
				// 获取资源文件流
				InputStream is = new FileInputStream(source);
				// 使用缓冲流提高效率
				BufferedInputStream bis = new BufferedInputStream(is);
				// 缓冲字节数组
				byte[] buffer = new byte[1024];
				int len = -1;
				// 将文件数据写入zip输出流
				while ((len = bis.read(buffer)) != -1) {
					zos.write(buffer, 0, len);
				}
				// 关闭流
				is.close();
				bis.close();
				// 关闭实体
				zos.closeEntry();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else { // 是文件夹
			// 列出文件夹的子文件数组
			File[] files = source.listFiles();
			// 如果source为空文件夹
			if (files == null || files.length == 0) {
				try {
					// 向zip输出流添加该文件夹的zip实体
					// 注意加上“/”代表是一个文件夹
					zos.putNextEntry(new ZipEntry(path + " /"));
					// 因为空文件夹没有数据所以不需要向zip写入数据
					// 关闭实体
					zos.closeEntry();
				} catch (IOException e) {
					e.printStackTrace();
				}
			} else { // 不是空文件夹
				for (File file : files) {
					// 递归实现层级压缩
					// 注意:path + "/" + file.getName()一定要加上原来路径才能保持原来层级关系
					compressFolder(file, zos, path + "/" + file.getName());
				}
			}
		}

	}

	// 测试的主方法
	public static void main(String[] args) throws FileNotFoundException {
		File source = new File("compress");
		OutputStream os = new FileOutputStream(new File("result.zip"));
		ZipOutputStream zos = new ZipOutputStream(os);
		compressFolder(source, zos, source.getName());
	}

}

解决内部文件夹名为"新建文件夹"时而不呈现文件的状态,原因是应为“夹”字汉字编码问题导致后一个字符不能正确展示“ /”可在斜杠前面添加一个空格

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

结果展示

没有压缩前的目录结构

java 文件压缩合并 java压缩多个文件夹_输出流


压缩后的目录结构

java 文件压缩合并 java压缩多个文件夹_java_02


java 文件压缩合并 java压缩多个文件夹_输出流_03

总结

如果在javaweb中要实现下载多级文件压缩文件夹是必不可少的,把response的outputstream传入即可