我有 zip 文件,它位于 zip 文件的文件夹中,请建议我如何使用 zip 输入流读取它。
例如:
abc.zip
|
documents/bcd.zip
如何读取 zip 文件中的 zip 文件?
如果您想递归地查看 zip 文件中的 zip 文件,
public void lookupSomethingInZip(InputStream fileInputStream) throws IOException {
ZipInputStream zipInputStream = new ZipInputStream(fileInputStream);
String entryName = "";
ZipEntry entry = zipInputStream.getNextEntry();
while (entry!=null) {
entryName = entry.getName();
if (entryName.endsWith("zip")) {
//recur if the entry is a zip file
lookupSomethingInZip(zipInputStream);
}
//do other operation with the entries..
entry=zipInputStream.getNextEntry();
}
}
使用从文件派生的文件输入流调用该方法 -
File file = new File(name);
lookupSomethingInZip(new FileInputStream(file));
以下代码片段列出了另一个 ZIP 文件中的 ZIP 文件的条目。使其适应您的需求。在引擎盖下ZipFile
使用ZipInputStream
s 。
代码片段使用Apache Commons IO,特别是IOUtils.copy
。
public static void readInnerZipFile(File zipFile, String innerZipFileEntryName) {
ZipFile outerZipFile = null;
File tempFile = null;
FileOutputStream tempOut = null;
ZipFile innerZipFile = null;
try {
outerZipFile = new ZipFile(zipFile);
tempFile = File.createTempFile("tempFile", "zip");
tempOut = new FileOutputStream(tempFile);
IOUtils.copy( //
outerZipFile.getInputStream(new ZipEntry(innerZipFileEntryName)), //
tempOut);
innerZipFile = new ZipFile(tempFile);
Enumeration<? extends ZipEntry> entries = innerZipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
System.out.println(entry);
// InputStream entryIn = innerZipFile.getInputStream(entry);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// Make sure to clean up your I/O streams
try {
if (outerZipFile != null)
outerZipFile.close();
} catch (IOException e) {
e.printStackTrace();
}
IOUtils.closeQuietly(tempOut);
if (tempFile != null && !tempFile.delete()) {
System.out.println("Could not delete " + tempFile);
}
try {
if (innerZipFile != null)
innerZipFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
readInnerZipFile(new File("abc.zip"), "documents/bcd.zip");
}
终于可以修复 Manas Maji 的答案了。最小的解决方案:
import java.io.*;
import java.nio.file.*;
import java.util.zip.*;
import org.slf4j.*;
public void readZipFileRecursive(final Path zipFile) {
try (final InputStream zipFileStream = Files.newInputStream(zipFile)) {
this.readZipFileStream(zipFileStream);
} catch (IOException e) {
LOG.error("error reading zip file %s!", zipFile, e);
}
}
private void readZipFileStream(final InputStream zipFileStream) {
final ZipInputStream zipInputStream = new ZipInputStream(zipFileStream);
ZipEntry zipEntry;
try {
while ((zipEntry = zipInputStream.getNextEntry()) != null) {
LOG.info("name of zip entry: {}", zipEntry.getName());
if (!zipEntry.isDirectory() && zipEntry.getName().endsWith(".zip")) {
this.readZipFileStream(zipInputStream); // recursion
}
}
} catch (IOException e) {
LOG.error("error reading zip file stream", e);
}
}
注意:不要以递归方法关闭流。
我编写了一个代码,可以将所有 zip 文件解压缩到一个 zip 文件中。它甚至可以解压缩到 n 级压缩。例如,如果您在 zip 文件中、在 zip 文件中(等等)有一个 zip 文件,它将提取所有文件。使用此类的 zipFileExtract 方法并将源 zip 文件和目标目录作为参数传递。
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
public class RecursiveFileExtract {
private static final int BUFFER_SIZE = 4096;
private static Queue<File> current;
private static List<File> visited;
public static void zipFileExtract(File sourceZipFile, File destinationDirectory) {
Path temp = null;
if(!destinationDirectory.exists())
{
destinationDirectory.mkdirs();
}
try {
temp = Files.move(Paths.get(sourceZipFile.getAbsolutePath()), Paths.get(destinationDirectory.getAbsolutePath()+File.separator+sourceZipFile.getName()));
} catch (IOException e) {
e.printStackTrace();
}
File zipFile = new File(temp.toAbsolutePath().toString());
current = new ConcurrentLinkedQueue<>();
visited = new ArrayList<>();
current.add(zipFile);
do {
unzipCurrent();
zipFinder(destinationDirectory);
}
while (!current.isEmpty());
}
private static void zipFinder(File directory) {
try {
if (directory != null) {
File fileArray[] = directory.listFiles();
if (fileArray != null) {
for (File file : fileArray) {
if (file != null) {
if (file.isDirectory()) {
zipFinder(file);
} else {
if (file.getName().endsWith(".zip")) {
if (!visited.contains(file)) {
current.add(file);
}
}
}
}
}
}
}
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
private static void unzipCurrent() {
try {
while (!current.isEmpty()) {
File file = current.remove();
visited.add(file);
File zipDirectory = new File(file.getParentFile().getAbsolutePath());
unzip(file.getAbsolutePath(), zipDirectory.getAbsolutePath());
}
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
public static void unzip(String zipFilePath, String destDirectory) {
try {
ZipInputStream zipIn = new ZipInputStream(new FileInputStream(zipFilePath));
ZipEntry entry = zipIn.getNextEntry();
while (entry != null) {
String filePath = destDirectory + File.separator + entry.getName();
if (!entry.isDirectory()) {
extractFile(zipIn, filePath);
} else {
File dir = new File(filePath);
Boolean result = dir.mkdir();
}
zipIn.closeEntry();
entry = zipIn.getNextEntry();
}
zipIn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
private static void extractFile(ZipInputStream zipIn, String filePath) {
try {
File file = new File(filePath);
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
Boolean result = parentFile.mkdirs();
if (!result) {
throw new Exception();
}
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(filePath));
byte[] bytesIn = new byte[BUFFER_SIZE];
int read = 0;
while ((read = zipIn.read(bytesIn)) != -1) {
bos.write(bytesIn, 0, read);
}
bos.close();
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
}