如何在Java中递归解压缩文件?
我有一个zip文件,其中包含一些其他zip文件 例如,邮件文件是如何在Java中递归解压缩文件?,java,unzip,Java,Unzip,我有一个zip文件,其中包含一些其他zip文件 例如,邮件文件是abc.zip,它包含xyz.zip,class1.java,class2.java。并且xyz.zip包含文件class3.java和class4.java File dir = new File("BASE DIRECTORY PATH"); FileFilter ff = new FileFilter() { @Override public boolean accept(File f) {
abc.zip
,它包含xyz.zip
,class1.java
,class2.java
。并且xyz.zip
包含文件class3.java
和class4.java
File dir = new File("BASE DIRECTORY PATH");
FileFilter ff = new FileFilter() {
@Override
public boolean accept(File f) {
//only want zip files
return (f.isFile() && f.getName().toLowerCase().endsWith(".zip"));
}
};
File[] list = null;
while ((list = dir.listFiles(ff)).length > 0) {
File file1 = list[0];
//TODO unzip the file to the base directory
}
因此,我需要使用Java将zip文件解压缩到一个文件夹中,该文件夹应该包含
class1.Java
、class2.Java
、class3.Java
和class4.Java
以下是一些未经测试的代码,这些代码基于我解压文件的一些旧代码
File dir = new File("BASE DIRECTORY PATH");
FileFilter ff = new FileFilter() {
@Override
public boolean accept(File f) {
//only want zip files
return (f.isFile() && f.getName().toLowerCase().endsWith(".zip"));
}
};
File[] list = null;
while ((list = dir.listFiles(ff)).length > 0) {
File file1 = list[0];
//TODO unzip the file to the base directory
}
public void doUnzip(String inputZip, String destinationDirectory)
throws IOException {
int BUFFER = 2048;
List zipFiles = new ArrayList();
File sourceZipFile = new File(inputZip);
File unzipDestinationDirectory = new File(destinationDirectory);
unzipDestinationDirectory.mkdir();
ZipFile zipFile;
// Open Zip file for reading
zipFile = new ZipFile(sourceZipFile, ZipFile.OPEN_READ);
// Create an enumeration of the entries in the zip file
Enumeration zipFileEntries = zipFile.entries();
// Process each entry
while (zipFileEntries.hasMoreElements()) {
// grab a zip file entry
ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
String currentEntry = entry.getName();
File destFile = new File(unzipDestinationDirectory, currentEntry);
destFile = new File(unzipDestinationDirectory, destFile.getName());
if (currentEntry.endsWith(".zip")) {
zipFiles.add(destFile.getAbsolutePath());
}
// grab file's parent directory structure
File destinationParent = destFile.getParentFile();
// create the parent directory structure if needed
destinationParent.mkdirs();
try {
// extract file if not a directory
if (!entry.isDirectory()) {
BufferedInputStream is =
new BufferedInputStream(zipFile.getInputStream(entry));
int currentByte;
// establish buffer for writing file
byte data[] = new byte[BUFFER];
// write the current file to disk
FileOutputStream fos = new FileOutputStream(destFile);
BufferedOutputStream dest =
new BufferedOutputStream(fos, BUFFER);
// read and write until last byte is encountered
while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, currentByte);
}
dest.flush();
dest.close();
is.close();
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
zipFile.close();
for (Iterator iter = zipFiles.iterator(); iter.hasNext();) {
String zipName = (String)iter.next();
doUnzip(
zipName,
destinationDirectory +
File.separatorChar +
zipName.substring(0,zipName.lastIndexOf(".zip"))
);
}
}
我使用ca.anderson4删除列表ZipFile并重写一点,这就是我得到的:
public class Unzip {
public void unzip(String zipFile) throws ZipException,
IOException {
System.out.println(zipFile);;
int BUFFER = 2048;
File file = new File(zipFile);
ZipFile zip = new ZipFile(file);
String newPath = zipFile.substring(0, zipFile.length() - 4);
new File(newPath).mkdir();
Enumeration zipFileEntries = zip.entries();
// Process each entry
while (zipFileEntries.hasMoreElements()) {
// grab a zip file entry
ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
String currentEntry = entry.getName();
File destFile = new File(newPath, currentEntry);
destFile = new File(newPath, destFile.getName());
File destinationParent = destFile.getParentFile();
// create the parent directory structure if needed
destinationParent.mkdirs();
if (!entry.isDirectory()) {
BufferedInputStream is = new BufferedInputStream(zip
.getInputStream(entry));
int currentByte;
// establish buffer for writing file
byte data[] = new byte[BUFFER];
// write the current file to disk
FileOutputStream fos = new FileOutputStream(destFile);
BufferedOutputStream dest = new BufferedOutputStream(fos,
BUFFER);
// read and write until last byte is encountered
while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, currentByte);
}
dest.flush();
dest.close();
is.close();
}
if (currentEntry.endsWith(".zip")) {
// found a zip file, try to open
unzip(destFile.getAbsolutePath());
}
}
}
public static void main(String[] args) {
Unzip unzipper=new Unzip();
try {
unzipper.unzip("test/test.zip");
} catch (ZipException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我测试了它,它可以工作在测试中,我注意到File.mkDirs()在Windows下不工作 /** *对于给定的完整路径名,请重新创建所有父目录 **/
private void createParentHierarchy(字符串parentName)引发IOException{
文件父项=新文件(父项名称);
字符串[]parentsStrArr=parent.getAbsolutePath().split(File.separator==“/”?“/”:“\\”;
//创建父对象的父对象
for(int i=0;i
警告,此处的代码适用于受信任的zip文件,在写入之前没有路径验证,如果使用它从未知客户端解压缩上载的zip文件,则可能会导致中所述的安全漏洞
此解决方案与先前发布的解决方案非常相似,但此解决方案在解压缩时重新创建了正确的文件夹结构
public static void extractFolder(String zipFile) throws IOException {
int buffer = 2048;
File file = new File(zipFile);
try (ZipFile zip = new ZipFile(file)) {
String newPath = zipFile.substring(0, zipFile.length() - 4);
new File(newPath).mkdir();
Enumeration<? extends ZipEntry> zipFileEntries = zip.entries();
// Process each entry
while (zipFileEntries.hasMoreElements()) {
// grab a zip file entry
ZipEntry entry = zipFileEntries.nextElement();
String currentEntry = entry.getName();
File destFile = new File(newPath, currentEntry);
File destinationParent = destFile.getParentFile();
// create the parent directory structure if needed
destinationParent.mkdirs();
if (!entry.isDirectory()) {
BufferedInputStream is = new BufferedInputStream(zip.getInputStream(entry));
int currentByte;
// establish buffer for writing file
byte[] data = new byte[buffer];
// write the current file to disk
FileOutputStream fos = new FileOutputStream(destFile);
try (BufferedOutputStream dest = new BufferedOutputStream(fos, buffer)) {
// read and write until last byte is encountered
while ((currentByte = is.read(data, 0, buffer)) != -1) {
dest.write(data, 0, currentByte);
}
dest.flush();
is.close();
}
}
if (currentEntry.endsWith(".zip")) {
// found a zip file, try to open
extractFolder(destFile.getAbsolutePath());
}
}
}
publicstaticvoidextractFolder(字符串zipFile)引发IOException{
int缓冲区=2048;
文件文件=新文件(zipFile);
试试看(ZipFile zip=新ZipFile(文件)){
字符串newPath=zipFile.substring(0,zipFile.length()-4);
新文件(newPath).mkdir();
枚举与NeilMonday的答案相同,但提取空目录:
static public void extractFolder(String zipFile) throws ZipException, IOException
{
System.out.println(zipFile);
int BUFFER = 2048;
File file = new File(zipFile);
ZipFile zip = new ZipFile(file);
String newPath = zipFile.substring(0, zipFile.length() - 4);
new File(newPath).mkdir();
Enumeration zipFileEntries = zip.entries();
// Process each entry
while (zipFileEntries.hasMoreElements())
{
// grab a zip file entry
ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
String currentEntry = entry.getName();
File destFile = new File(newPath, currentEntry);
//destFile = new File(newPath, destFile.getName());
File destinationParent = destFile.getParentFile();
// create the parent directory structure if needed
destinationParent.mkdirs();
if (!entry.isDirectory())
{
BufferedInputStream is = new BufferedInputStream(zip
.getInputStream(entry));
int currentByte;
// establish buffer for writing file
byte data[] = new byte[BUFFER];
// write the current file to disk
FileOutputStream fos = new FileOutputStream(destFile);
BufferedOutputStream dest = new BufferedOutputStream(fos,
BUFFER);
// read and write until last byte is encountered
while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, currentByte);
}
dest.flush();
dest.close();
is.close();
}
else{
destFile.mkdirs()
}
if (currentEntry.endsWith(".zip"))
{
// found a zip file, try to open
extractFolder(destFile.getAbsolutePath());
}
}
}
解压后应关闭zip文件
static public void extractFolder(String zipFile) throws ZipException, IOException
{
System.out.println(zipFile);
int BUFFER = 2048;
File file = new File(zipFile);
ZipFile zip = new ZipFile(file);
try
{
...code from other answers ( ex. NeilMonday )...
}
finally
{
zip.close();
}
}
根据需要进行修改,然后加入一些最佳答案。此版本将:
- 递归地将zip提取到给定位置
- 创建空目录
- 把拉链关好
下面是一些代码,经过测试,这些代码运行良好:
package com.test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class Unzipper {
private final static int BUFFER_SIZE = 2048;
private final static String ZIP_FILE = "/home/anton/test/test.zip";
private final static String DESTINATION_DIRECTORY = "/home/anton/test/";
private final static String ZIP_EXTENSION = ".zip";
public static void main(String[] args) {
System.out.println("Trying to unzip file " + ZIP_FILE);
Unzipper unzip = new Unzipper();
if (unzip.unzipToFile(ZIP_FILE, DESTINATION_DIRECTORY)) {
System.out.println("Succefully unzipped to the directory "
+ DESTINATION_DIRECTORY);
} else {
System.out.println("There was some error during extracting archive to the directory "
+ DESTINATION_DIRECTORY);
}
}
public boolean unzipToFile(String srcZipFileName,
String destDirectoryName) {
try {
BufferedInputStream bufIS = null;
// create the destination directory structure (if needed)
File destDirectory = new File(destDirectoryName);
destDirectory.mkdirs();
// open archive for reading
File file = new File(srcZipFileName);
ZipFile zipFile = new ZipFile(file, ZipFile.OPEN_READ);
//for every zip archive entry do
Enumeration<? extends ZipEntry> zipFileEntries = zipFile.entries();
while (zipFileEntries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
System.out.println("\tExtracting entry: " + entry);
//create destination file
File destFile = new File(destDirectory, entry.getName());
//create parent directories if needed
File parentDestFile = destFile.getParentFile();
parentDestFile.mkdirs();
if (!entry.isDirectory()) {
bufIS = new BufferedInputStream(
zipFile.getInputStream(entry));
int currentByte;
// buffer for writing file
byte data[] = new byte[BUFFER_SIZE];
// write the current file to disk
FileOutputStream fOS = new FileOutputStream(destFile);
BufferedOutputStream bufOS = new BufferedOutputStream(fOS, BUFFER_SIZE);
while ((currentByte = bufIS.read(data, 0, BUFFER_SIZE)) != -1) {
bufOS.write(data, 0, currentByte);
}
// close BufferedOutputStream
bufOS.flush();
bufOS.close();
// recursively unzip files
if (entry.getName().toLowerCase().endsWith(ZIP_EXTENSION)) {
String zipFilePath = destDirectory.getPath() + File.separatorChar + entry.getName();
unzipToFile(zipFilePath, zipFilePath.substring(0,
zipFilePath.length() - ZIP_EXTENSION.length()));
}
}
}
bufIS.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
package.com.test;
导入java.io.BufferedInputStream;
导入java.io.BufferedOutputStream;
导入java.io.File;
导入java.io.FileOutputStream;
导入java.util.Enumeration;
导入java.util.zip.ZipEntry;
导入java.util.zip.ZipFile;
公共类{
私有最终静态int缓冲区大小=2048;
私有最终静态字符串ZIP_FILE=“/home/anton/test/test.ZIP”;
私有最终静态字符串DESTINATION_DIRECTORY=“/home/anton/test/”;
私有最终静态字符串ZIP_扩展名=“.ZIP”;
公共静态void main(字符串[]args){
System.out.println(“尝试解压缩文件”+ZIP_文件);
解压拉链解压=新的解压拉链();
if(unzip.unzipToFile(ZIP_文件,目的地_目录)){
System.out.println(“成功解压缩到目录”
+目的地目录);
}否则{
System.out.println(“将存档文件提取到目录时出错”
+目的地目录);
}
}
公共布尔unzipToFile(字符串srcZipFileName,
字符串(目录名){
试一试{
BufferedInputStream bufIS=null;
//创建目标目录结构(如果需要)
File destDirectory=新文件(destDirectoryName);
destDirectory.mkdirs();
//打开档案以供阅读
File File=新文件(srcZipFileName);
ZipFile ZipFile=新ZipFile(文件,ZipFile.OPEN_READ);
//对于每个zip存档条目,请执行以下操作
Enumeration该代码实际上是由ca.anderson4编写的;我只是编辑了它(我不喜欢左右滚动).aaa好的,我没有看到:-)。所以我给ca.anderson4和你的编辑器评分;-)这个只是将所有子文件夹中的所有文件转储到一个文件夹中,从而破坏了整个存档结构。为什么你有一个抛出声明,但却实际捕获异常并记录它?这难道不意味着调用方将期待IOT异常吗帽子永远不会被抛出..?谢谢你提供了这个,非常有用!如果条目是一个目录呢?@Charlie我不认为这是真的。如果我使用PeaZip提取一个包含目录结构的zip,结果目录会正确地重新创建文件夹结构。这个方法(看起来),获取所有文件,不管它们的目录结构是什么,只需将它们放在基本目标目录中即可。删除第47行destFile=new File(unzipdestinitiondirectory,destFile.getName())后,上面的代码工作得非常好;谢谢这个函数救了我的命。我们项目中的一些预先编写的zip函数根本无法提取文件中的文件夹。这非常有效。非常感谢分享。我很惊讶这个答案没有被接受。无论如何,请再次向上投你的票,谢谢。我知道这很旧,但是注释掉的行有什么意义//destFile=new File(newPath,destFile.getName());
如果有,留在?@Liam中没有什么意义。我想我只是在尝试获取当前文件名的不同方法。我决定使用currentEntry
而不是destFile.getName(
package com.test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class Unzipper {
private final static int BUFFER_SIZE = 2048;
private final static String ZIP_FILE = "/home/anton/test/test.zip";
private final static String DESTINATION_DIRECTORY = "/home/anton/test/";
private final static String ZIP_EXTENSION = ".zip";
public static void main(String[] args) {
System.out.println("Trying to unzip file " + ZIP_FILE);
Unzipper unzip = new Unzipper();
if (unzip.unzipToFile(ZIP_FILE, DESTINATION_DIRECTORY)) {
System.out.println("Succefully unzipped to the directory "
+ DESTINATION_DIRECTORY);
} else {
System.out.println("There was some error during extracting archive to the directory "
+ DESTINATION_DIRECTORY);
}
}
public boolean unzipToFile(String srcZipFileName,
String destDirectoryName) {
try {
BufferedInputStream bufIS = null;
// create the destination directory structure (if needed)
File destDirectory = new File(destDirectoryName);
destDirectory.mkdirs();
// open archive for reading
File file = new File(srcZipFileName);
ZipFile zipFile = new ZipFile(file, ZipFile.OPEN_READ);
//for every zip archive entry do
Enumeration<? extends ZipEntry> zipFileEntries = zipFile.entries();
while (zipFileEntries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
System.out.println("\tExtracting entry: " + entry);
//create destination file
File destFile = new File(destDirectory, entry.getName());
//create parent directories if needed
File parentDestFile = destFile.getParentFile();
parentDestFile.mkdirs();
if (!entry.isDirectory()) {
bufIS = new BufferedInputStream(
zipFile.getInputStream(entry));
int currentByte;
// buffer for writing file
byte data[] = new byte[BUFFER_SIZE];
// write the current file to disk
FileOutputStream fOS = new FileOutputStream(destFile);
BufferedOutputStream bufOS = new BufferedOutputStream(fOS, BUFFER_SIZE);
while ((currentByte = bufIS.read(data, 0, BUFFER_SIZE)) != -1) {
bufOS.write(data, 0, currentByte);
}
// close BufferedOutputStream
bufOS.flush();
bufOS.close();
// recursively unzip files
if (entry.getName().toLowerCase().endsWith(ZIP_EXTENSION)) {
String zipFilePath = destDirectory.getPath() + File.separatorChar + entry.getName();
unzipToFile(zipFilePath, zipFilePath.substring(0,
zipFilePath.length() - ZIP_EXTENSION.length()));
}
}
}
bufIS.close();
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}