日常生活中我们最常用的就是压缩软件来压缩文件或解压,在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中。