您的位置:首页 > 编程语言

分享(非充分)利用NIO2进行压缩处理的代码

2014-11-23 01:42 211 查看
这几天帮女友做的程序需要用到zip打包压缩的功能。

又正好在研究NIO2,好吧...确实是很古老的东西了...

不过在网上找了一些文章以后,发现内容更古老...

于是想自己更新一下内容,看看NIO2可以对程序做出一些什么样的变化。

代码中没有用到强大的walkFileTree,用DirectoryStream的递归实现,之后有时间的话,再去研究下walkFileTree。

有什么可以优化的地方,也希望各位不吝赐教。

package com.task;

import java.io.File;
import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipProcess {

	private static ZipOutputStream zos;
	static Path pathRoot = Paths.get("C:" + File.separator + "scan"
	/* + File.separator + "a.pdf" */);

	public static void zipProcess(Path path) throws IOException {
		pathRoot = path;
		System.out.println("需要压缩的路径是:" + pathRoot.toString());
		/*
		 * 首先,传进来一个path参数,这个参数表达着我们所要压缩的对象 可以是一个文件,也可以是一个文件夹
		 * 如果是文件的话,只需要将扩展名转变为.zip即可 如果是文件夹的话,只需要在PATH路径后,增加.zip即可。
		 * 生成的字符串,用作ZipEntry
		 */
		StringBuilder sb = new StringBuilder();
		if (!Files.isDirectory(pathRoot)) {
			String[] tempString = pathRoot.toString().split("\\.");
			// 因为.在正则表达式中,代表任意字符,所以要使用"."时,需要转义
			for (int i = 0; i < tempString.length - 1; i++) {
				sb.append(tempString[i]);
			}
		} else {
			sb.append(pathRoot.toString());// 如果pathRoot是文件夹
		}
		String zosName = sb.append(".zip").toString();
		// 至此,zos已经获得了。
		zos = new ZipOutputStream(Files.newOutputStream(Paths.get(zosName)));
		// 接下来做判断,是否是文件
		// 1、如果是文件
		if (!Files.isDirectory(pathRoot)) {
			// 把文件名作为zipEntry添加进Zip文件
			System.out.println("xxx:" + pathRoot.getFileName().toString());
			zos.putNextEntry(new ZipEntry(pathRoot.getFileName().toString()));
			zosReadAndWrite(pathRoot);// 多亏Files的readAllBytes方法,不需要再有InputStream去读字节了。
		}
		// 2、如果是路径的话,就获取DirectoryStream,做遍历
		else {
			checkAndWrap(pathRoot);
		}

		// 确定了输出流,设定完了ZIP文件的根位置以后,就开始对路径做DirectoryStream
		// 传根位置进方法,做递归:如果该位置为文件,做ZipEntry的增加,并且做相应的ZipOutputStream的write操作。

		// 以下是ZipEntry的标准获取格式。
		System.out.println();

		zos.close();
	}

	private static void zosReadAndWrite(Path in) throws IOException {
		zos.write(Files.readAllBytes(in));
	}

	private static void checkAndWrap(Path pRoot) throws IOException {
		// 能够传进来的参数,一定是指定路径的,那么,第一步就是获取DirectoryStream了
		try (DirectoryStream<Path> ds = Files.newDirectoryStream(pRoot)) {
			try (DirectoryStream<Path> dsTemp = Files.newDirectoryStream(pRoot)) {
				if (!dsTemp.iterator().hasNext()) {
					zos.putNextEntry(new ZipEntry(pathRoot.relativize(pRoot)
							.toString() + "/"));
					// 如果是空文件夹,只需要putNextEntry即可。结尾需要加"/"。
				} else {
					for (Path p : ds) {
						if (Files.isDirectory(p)) {
							checkAndWrap(p);
						} else {
							zos.putNextEntry(new ZipEntry(pathRoot
									.relativize(p).toString()));
							zosReadAndWrite(p);
						}
					}
				}
			}
		}
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: