java中压缩文件的解析方式

    日常生活中我们最常用的就是压缩软件来压缩文件或解压,在java中也可以通过IO流操作来将文件进行压缩解压操作。

 1、解压.zip和.rar格式的文件。

package com.apesource.demo01IO流;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Comparator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import org.apache.commons.io.FileUtils;

import com.github.junrar.Archive;
import com.github.junrar.exception.RarException;
import com.github.junrar.rarfile.FileHeader;

public class JavaDemo02 {
	public static void main(String[] args) {
		String path = "D:\\text\\实验案例.rar";

		if (path.endsWith(".zip")) {
			unzip(path);
		} else if (path.endsWith(".rar")) {
			unrar(path);
		}
	}

	// 解压缩zip格式
	public static void unzip(String path) {
		// 根据原始路径(字符串),创建源文件(File对象)
		File sourceFile = new File(path);

		// 根目录
		String sourceFileName = sourceFile.getName();
		File rootDir = new File(
				sourceFile.getParent() + "\\" + sourceFileName.substring(0, sourceFileName.lastIndexOf(".")));

		// 判断根目录是否已经存在
		if (rootDir.exists()) {
			// 如果存在
			// rootDir.delete(); // 仅能删除空目录

			// 使用commons-io包提供的FileUtils工具类进行删除
			try {
				FileUtils.deleteDirectory(rootDir);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		// 创建根目录
		rootDir.mkdir();

		// ZipInputStream: 用于进行zip格式的压缩文件输入流
		try (ZipInputStream in = new ZipInputStream(new FileInputStream(sourceFile))) {
			// 遍历压缩包中的每个子目录或子文件(ZipEntry类型的对象)
			ZipEntry zipEntry = null;
			while ((zipEntry = in.getNextEntry()) != null) {
				// 创建子目录或子文件(File对象)
				File file = new File(rootDir.getPath() + "\\" + zipEntry.getName());

				if (zipEntry.isDirectory()) {
					// 物理磁盘创建子目录
					file.mkdir();
				} else {
					// 物理磁盘创建子文件
					file.createNewFile();

					// 读取当前压缩包中的子文件,并通过输出流out写入新子文件中
					try (FileOutputStream out = new FileOutputStream(file)) {
						byte[] buff = new byte[1024];
						int len = -1;
						while ((len = in.read(buff)) != -1) {
							out.write(buff, 0, len);
						}
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	// 解压缩rar格式
	public static void unrar(String path) {
		// 1.创建解压缩的根目录
		File rarFile = new File(path);
		File rootDir = new File(
				rarFile.getParent() + "\\" + rarFile.getName().substring(0, rarFile.getName().lastIndexOf(".")));
		if (rootDir.exists()) {
			try {
				FileUtils.deleteDirectory(rootDir);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		rootDir.mkdir();

		// 创建Archive对象,用于读取rar压缩包文件格式
		try (Archive archive = new Archive(new FileInputStream(path))) {

			// 获取压缩文件中的所有子目录或子文件(FileHeader对象)
			List<FileHeader> fileHeaderList = archive.getFileHeaders();

			// 按照子目录(子文件)名称排序
			fileHeaderList.sort(new Comparator<FileHeader>() {
				@Override
				public int compare(FileHeader o1, FileHeader o2) {
					return o1.getFileName().compareTo(o2.getFileName());
				}
			});

			// 遍历子目录和文件
			for (FileHeader fd : fileHeaderList) {
				System.out.println(fd.getFileName());
				File f = new File(rootDir.getPath() + "\\" + fd.getFileName());

				if (fd.isDirectory()) {
					// 创建新子目录
					f.mkdir();
				} else {
					// 创建新子文件
					f.createNewFile();

					// 获取压缩包中的子文件输入流
					InputStream in = archive.getInputStream(fd);

					// 复制文件输入流至新子文件
					FileUtils.copyInputStreamToFile(in, f);
				}
			}

		} catch (RarException | IOException e) {
			e.printStackTrace();
		}
	}
}

(1)解压zip文件

  • 将传入的路径字符串传入对象'sourceFile'。
  • 用拼接字符串调用.getParent()方法获得父级目录,再用拼接符号拼接创建根目录rootDir。
  • 写调用方法.exists()方法判断是否目录已经存在,如果已经存在,则调用FileUtils中的方法deleteDirectory()方法进行删除,如若没有,则创建根目录。
  • 使用ZipInputStream读取zip文件。
  • 调用方法.getNextEntry()方法遍历压缩包中的每个目录或子文件,如果是目录则直接创建目录,如果是文件则创建子文件并将其写入新文件中(创建byte[]数组进行接收,直到读完为止),完成解压。

(2)解压rar文件

  • 将传入的路径字符串传入对象'rarFile'。
  • 用拼接字符串调用.getParent()方法获得父级目录,再用拼接符号拼接创建根目录rootDir。
  • 写调用方法.exists()方法判断是否目录已经存在,如果已经存在,则调用FileUtils中的方法deleteDirectory()方法进行删除,如若没有,则创建根目录。
  • 创建Archive对象读取rar文件。
  • 调用getFileHeaders()方法获取压缩文件中的所有子目录或子文件。
  • 重写sort中的compare方法,实现目录在子文件上方。
  • 调用方法.getInputStream()获取压缩包的子文件输入流,再将文件输入流复制至新子文件。

2、 压缩.zip文件

package com.apesource.demo01IO流;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class JavaDemo05 {
	public static void main(String[] args) {
		// 所在目录
		File dir = new File("D:\\text\\rootPath");

		// 获取所有原始子文件
		File[] files = dir.listFiles();

		// 创建zip压缩文件的输出流
		try (ZipOutputStream out = new ZipOutputStream(
				new FileOutputStream(dir.getPath() + "\\" + dir.getName() + ".zip"))) {

			// 遍历所有原始子文件
			for (File f : files) {
				// 写入一个压缩包中的子文件(ZipEntry对象)
				out.putNextEntry(new ZipEntry(f.getName()));

				// 写入字节内容
				out.write(Files.readAllBytes(f.toPath()));

				// 关闭压缩包中的子文件
				out.closeEntry();
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
  • 创建一个ZipOutputStream对象,将准备解压的.zip文件生成。
  • 遍历所有原始子文件,调用一个putNextEntry()方法,创建一个新的ZipEntry对象,将其添加到zip文件中。
  • 调用readAllBytes方法读取文件的所有字节并返回一个字节数组,将字节数组写入ZipEntry中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值