【问题标题】:How to access a zip file into a zip file in Java如何在 Java 中将 zip 文件访问为 zip 文件
【发布时间】:2015-03-16 11:17:50
【问题描述】:

我正在尝试读取位于 zip 文件中的 .srt 文件,这些文件位于 zip 文件中。我成功读取了简单 zip 中的 .srt 文件,并提取了以下代码:

    for (Enumeration enume = fis.entries(); enume.hasMoreElements();) {
                ZipEntry entry = (ZipEntry) enume.nextElement();
                fileName = entry.toString().substring(0,entry.toString().length()-4);
try {
                    InputStream in = fis.getInputStream(entry);
                    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String ext = entry.toString().substring(entry.toString().length()-4, entry.toString().length());

但现在我不知道如何才能访问 zip 文件中的 zip 文件。 我尝试使用 ZipFile fis = new ZipFile(filePath) ,其中 filePath 是 zip 文件的路径 + 内部 zip 文件的名称。它没有识别路径,所以我不知道我是否清楚。

谢谢。

【问题讨论】:

  • 您需要扫描文件还是可以确定明确的路径?如果您有路径,我认为您可以使用 URL。
  • 我必须扫描 zip 文件才能知道里面文件的路径。扫描之前不知道压缩包里面的文件名是什么。
  • 将每个符合条件的条目包装在一个新的 ZipInputStream 中。
  • 我认为这是我需要的,我会研究它,我不知道如何使用它。谢谢。

标签: java zip


【解决方案1】:

ZipFile 仅适用于真实文件,因为它旨在用作随机访问机制,需要能够直接查找文件中的特定位置以按名称读取条目。但正如 VGR 在 cmets 中建议的那样,虽然您无法随机访问 zip-inside-a-zip,但您可以使用ZipInputStream,它提供严格的顺序访问条目并使用任何InputStream 的 zip 格式数据。

但是,与其他流相比,ZipInputStream 的使用模式有点奇怪 - 调用 getNextEntry 读取条目元数据并将流定位以读取该条目的数据,您从 ZipInputStream 读取直到它报告 EOF,然后在转到流中的下一个条目之前,您(可选)调用 closeEntry()

关键点是你不能 close() ZipInputStream 直到你读完最后一个条目,所以取决于你想对你可能需要使用的条目数据做什么像commons-io CloseShieldInputStream 这样的东西来防止流过早关闭。

try(ZipInputStream outerZip = new ZipInputStream(fis)) {
  ZipEntry outerEntry = null;
  while((outerEntry = outerZip.getNextEntry()) != null) {
    if(outerEntry.getName().endsWith(".zip")) {
      try(ZipInputStream innerZip = new ZipInputStream(
                  new CloseShieldInputStream(outerZip))) {
        ZipEntry innerEntry = null;
        while((innerEntry = innerZip.getNextEntry()) != null) {
          if(innerEntry.getName().endsWith(".srt")) {
            // read the data from the innerZip stream
          }
        }
      }
    }
  }
}

【讨论】:

  • 是否有可能使其递归,因为 zip 文件中的 zip 文件中可能存在 zip 文件等...
  • “从 innerZip 流中读取数据” 有人能指点我怎么做吗?
【解决方案2】:

找到递归提取 .zip 文件的代码:

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();
    }

    if (currentEntry.endsWith(".zip"))
    {
        // found a zip file, try to open
        extractFolder(destFile.getAbsolutePath());
    }
}
}

【讨论】:

  • 如果我理解的话,此方法将提取 zip 文件中的所有内容并创建一个文件夹将所有内容放入其中。我一直在寻找不需要提取并且可以读取 zip 文件中的文件的东西。如果没有其他解决方案,我会采取这个。
  • 您可以修改部分代码以访问 zipfile 中的 zipfile:if (currentEntry.endsWith(".zip")) { // found a zip file, try to read // write a read .zip code here. }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 1970-01-01
相关资源
最近更新 更多