【问题标题】:Getting specific file from ZipInputStream从 ZipInputStream 获取特定文件
【发布时间】:2015-06-13 10:51:23
【问题描述】:

我可以通过ZipInputStream,但在开始迭代之前,我想获得一个我在迭代期间需要的特定文件。我该怎么做?

ZipInputStream zin = new ZipInputStream(myInputStream)
while ((entry = zin.getNextEntry()) != null)
 {
    println entry.getName()
}

【问题讨论】:

  • 我不明白...迭代这些条目直到你得到你想要的,然后处理它?
  • 首先迭代到文件并以您想要的方式存储它。然后再次迭代。
  • 还有 ZipFile (java
  • tim_yates:有问题的文件是处理其他文件所必需的。因此,如果第一次迭代该文件不是我想要的,我将无法再处理它。

标签: java file-io groovy inputstream zipinputstream


【解决方案1】:

Finding a file in zip entry

ZipFile file = new ZipFile("file.zip");
ZipInputStream zis = searchImage("foo.png", file);

public searchImage(String name, ZipFile file)
{
  for (ZipEntry e : file.entries){
    if (e.getName().endsWith(name)){
      return file.getInputStream(e);
    }
  }

  return null;
}

【讨论】:

  • 方法“searchImage”缺少返回类型“ZipInputStream”。
【解决方案2】:

使用 ZipEntry 上的 getName() 方法获取您想要的文件。

ZipInputStream zin = new ZipInputStream(myInputStream)
String myFile = "foo.txt";
while ((entry = zin.getNextEntry()) != null)
{
    if (entry.getName().equals(myFileName)) {
        // process your file
        // stop looking for your file - you've already found it
        break;
    }
}

从 Java 7 开始,如果您只需要一个文件并且有一个文件可以读取,则最好使用 ZipFile 而不是 ZipStream:

ZipFile zfile = new ZipFile(aFile);
String myFile = "foo.txt";
ZipEntry entry = zfile.getEntry(myFile);
if (entry) {
     // process your file           
}

【讨论】:

  • 对于您的第一个代码:请参阅我对 tim_yates 的回复。对于您的第二代码:我认为有类似于 ZipFile 的东西。所以对于我的情况应该使用 ZipFile。
【解决方案3】:

如果您正在使用的myInputStream 来自磁盘上的真实文件,那么您可以简单地使用java.util.zip.ZipFile,它由RandomAccessFile 支持,并通过名称提供对zip 条目的直接访问。但是,如果您只有一个InputStream(例如,如果您在从网络套接字或类似接口接收到的流时直接处理流),那么您将不得不自己进行缓冲。

您可以将流复制到一个临时文件,然后使用ZipFile 打开该文件,或者如果您事先知道数据的最大大小(例如,对于预先声明其Content-Length 的HTTP 请求),您可以使用BufferedInputStream 将其缓冲在内存中,直到找到所需的条目。

BufferedInputStream bufIn = new BufferedInputStream(myInputStream);
bufIn.mark(contentLength);
ZipInputStream zipIn = new ZipInputStream(bufIn);
boolean foundSpecial = false;
while ((entry = zin.getNextEntry()) != null) {
  if("special.txt".equals(entry.getName())) {
    // do whatever you need with the special entry
    foundSpecial = true;
    break;
  }
}

if(foundSpecial) {
  // rewind
  bufIn.reset();
  zipIn = new ZipInputStream(bufIn);
  // ....
}

(我自己没有测试过这段代码,你可能会发现有必要在bufIn和第一个zipIn之间使用commons-io CloseShieldInputStream之类的东西,以允许第一个zip流关闭无需关闭底层bufIn,然后再重新上链)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-05
    • 2016-07-18
    • 2014-08-19
    • 1970-01-01
    • 2012-06-21
    • 1970-01-01
    • 2015-06-23
    相关资源
    最近更新 更多