java解压zip文件并为文件添加前缀
要在Java中解压ZIP文件时考虑以上所有要求,我们需要确保使用正确的编码来读取文件名,并且一旦检测到文件大小不符合要求,我们就需要停止解压并清理已解压的文件。下面是一个改进后的示例代码:
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class ZipExtractor {
private static final long MIN_FILE_SIZE = 40 * 1024; // 40K
private static final long MAX_FILE_SIZE = 200 * 1024; // 200K
private static final String PREFIX = "your_prefix_"; // 替换为你的前缀
/**
* 解压文件并重命名解压出来的文件
*
* @param zipFile 要解压的文件
* @param destDirectory 解压位置
* @param prefix 前缀
*/
public static void unzipAndRename(File zipFile, String destDirectory, String prefix) throws IOException {
List<File> extractedFiles = new ArrayList<>(); // 跟踪已解压的文件
try (ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"))) {
// 确保目标目录存在
File dir = new File(destDirectory);
if (!dir.exists() && !dir.mkdirs()) {
throw new RuntimeException("创建文件夹失败");
}
// 遍历ZIP文件中的所有条目
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
String fileName = entry.getName();
long max_file_size = 200 * 1024; // 200K
long min_file_size = 40 * 1024; // 40K
// 检查文件大小
if (entry.getSize() < min_file_size || entry.getSize() > max_file_size) {
throw new IOException("文件大小不在要求的范围内: " + fileName);
}
// 重新命名文件(如果需要)
if (!fileName.startsWith(prefix)) {
fileName = prefix + fileName;
}
File entryDestination = new File(destDirectory, fileName);
extractedFiles.add(entryDestination); // 添加已解压文件到列表
if (!entry.isDirectory()){
entryDestination.mkdirs();
}else {
entryDestination.getParentFile().mkdirs();
try (InputStream in = zip.getInputStream(entry);
FileOutputStream out = new FileOutputStream(entryDestination)) {
byte[] buffer = new byte[2048];
int length;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
}
}
}
} catch (IOException e) {
// 如果有任何文件大小不符合要求,删除已解压的文件
if (e.getMessage().contains("文件大小不在要求的范围内")) {
for (File file : extractedFiles) {
if (file.exists() && file.delete()) {
System.out.println("Deleted: " + file.getAbsolutePath());
}
}
}
throw e;
}
}
public static void main(String[] args) {
String zipFilePath = "path_to_your_zip_file.zip"; // 替换为你的ZIP文件路径
String destDir = "path_to_extract_directory"; // 替换为解压目标目录
try {
extractZip(zipFilePath, destDir, PREFIX);
} catch (IOException e) {
e.printStackTrace();
}
}
}请注意以下几点:
我们使用
StandardCharsets.GBK作为ZipInputStream的第二个参数来确保文件名以GBK编码读取,从而防止中文乱码。但是,不是所有的ZIP文件都会以GBK编码其文件名,这取决于创建ZIP文件的系统。如果ZIP文件中的文件名使用的是UTF-8或其他编码,你需要相应地更改。我们维护了一个
List<File>来跟踪已解压的文件,并在检测到不符合要求的文件大小时删除它们。在实际生产环境中,你可能需要更复杂的错误处理逻辑,比如记录日志、通知用户等。
请确保你有足够的权限来删除文件,否则
file.delete()方法将不会成功。如果ZIP文件非常大,你可能需要考虑在解压过程中使用更高效的内存管理策略,比如流式处理文件内容而不是一次性加载整个文件到内存中。
评论 (0)