压缩流解压流
介绍
压缩流和解压流是在文件处理中常用的功能,用于将文件或文件夹进行压缩和解压缩操作。本文将介绍压缩流和解压流的基本概念、常用API和案例示例。
压缩流
ZipOutputStream
ZipOutputStream是Java中用于创建ZIP文件的输出流。它提供了一系列方法来添加文件或文件夹到ZIP文件中,并可以设置压缩级别和压缩方法。
常用API
方法 | 描述 |
---|---|
ZipOutputStream | 创建新的ZIP输出流 |
close | 关闭ZIP输出流和正在过滤的流 |
closeEntry | 关闭当前ZIP条目并定位流以写入下一个条目 |
finish | 完成写入ZIP输出流的内容,无需关闭底层流 |
putNextEntry | 开始写入新的ZIP文件条目并将流定位到条目数据的开始处 |
setComment | 设置ZIP文件注释 |
setLevel | 为后续的DEFLATED条目设置压缩级别 |
setMethod | 设置用于后续条目的默认压缩方法 |
write | 将字节数组写入当前ZIP条目数据 |
补充资料:
解压流
ZipInputStream
ZipInputStream是Java中用于读取ZIP文件的输入流。它提供了一系列方法来读取ZIP文件中的条目,并可以跳过或关闭当前条目。
常用API
方法 | 描述 |
---|---|
ZipInputStream | 创建新的ZIP输入流 |
available | 在EOF到达当前条目数据后,返回0;否则,始终返回1 |
close | 关闭此输入流并释放与此流关联的所有系统资源 |
closeEntry | 关闭当前ZIP条目并定位流以读取下一个条目 |
createZipEntry | 为指定条目名称创建一个新的ZipEntry对象 |
getNextEntry | 读取下一个ZIP文件条目并将流定位到该条目数据的开始处 |
read | 从当前ZIP条目读入字节数组 |
skip | 跳过当前ZIP条目中指定的字节数 |
补充资料:
案例
/**
* 获取指定文件夹中所有文件的路径列表
*
* @param path 源文件夹地址
* @return 返回Map<String, Boolean>,String 路径|Boolean 判断是否是文件(true 文件|false 文件夹)
*/
public static Map<String, Boolean> getFileFolderPathMap(String path) {
// 初始化路径列表
Map<String, Boolean> map = new HashMap<>();
// 遍历源文件夹中的所有文件
for (String file : new File(path).list()) {
// 构造当前文件的路径
String paths = path + '\\' + file;
// 如果当前文件是文件夹,则递归获取该文件夹中的所有文件
// 并将其文件夹路径添加到路径列表中
if (new File(paths).isDirectory()) {
map.put(paths, false);
map.putAll(getFileFolderPathMap(paths));
} else {
// 如果当前文件是普通文件,则将其路径添加到路径列表中
map.put(paths, true);
}
}
// 返回路径列表
return map;
}
/**
* 压缩文件夹
*
* @param folderPath 源路径
* @param zipPath 压缩包存放路径/压缩包名称(不需要".zip"后缀)
* @throws IOException
*/
public static void zipOutputFolder(String folderPath, String zipPath) throws IOException {
// 创建压缩流,传入文件输出流
ZipOutputStream zipOutputStream = new ZipOutputStream(new FileOutputStream(zipPath + ".zip"));
// 获取指定文件夹中所有文件的路径列表
Map<String, Boolean> map = getFileFolderPathMap(folderPath);
// 遍历路径列表
for (String paths : map.keySet()) {
// 判断是否是文件
if (map.get(paths)) {
// 在zip流中创建一个ZIP条目,接受一个 ZipEntry 对象作为参数
// 获取相对于 readPath 的相对路径,作为新的 ZipEntry 的名称
zipOutputStream.putNextEntry(new ZipEntry(paths.replace(folderPath + "\\", "")));
// 创建一个文件输入流,用于写入压缩流
FileInputStream inputStream = new FileInputStream(paths);
// 创建一个长度为文件长度的字节数组
byte[] bytes = new byte[(int) new File(paths).length()];
// 输入流中读取数据到字节数组
if (inputStream.read(bytes) != -1) {
// 将文件数据写入压缩流
zipOutputStream.write(bytes);
}
inputStream.close();
}
}
zipOutputStream.close();
}
/**
* 解压文件夹
*
* @param folderPath 解压的目标路径(不需要"\\"后缀)
* @param zipPath 压缩包存放路径/压缩包名称(不需要".zip"后缀)
*/
public static void zipInputFolder(String folderPath, String zipPath) throws IOException {
// 添加文件夹路径和ZIP文件扩展名
folderPath = folderPath + "\\";
zipPath = zipPath + ".zip";
// 创建ZIP输入流
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipPath));
ZipEntry zipEntry;
// 逐个解压ZIP条目
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
// 构造ZIP条目对应的文件对象
File file = new File(folderPath + zipEntry.getName());
if (!file.getParentFile().exists()) {
// 判断解压后文件的父目录是否存在,如果不存在,则使用 mkdirs() 方法创建该目录。这样确保解压后的文件可以被正确地存储在对应的目录中。
file.getParentFile().mkdirs();
}
// 创建输出流和输入流
OutputStream outputStream = new FileOutputStream(file);
InputStream inputStream = new ZipFile(zipPath).getInputStream(zipEntry);
// 逐个读取字节并写入文件
byte[] bytes = new byte[1024];
int length = 0;
while ((length = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, length);
}
// 逐个读取字节并写入文件
outputStream.close();
inputStream.close();
}
// 关闭ZIP输入流
zipInputStream.close();
}