BufferedReader readLine 返回 null

我有一个 zip 文件,其中包含我想要阅读的 9 个文件。所以我实现了以下功能:


public static Map<String, BufferedReader> unzipFile(InputStream zippedFile) throws IOException {

  ZipInputStream zipInputStream = new ZipInputStream(zippedFile);

  HashMap<String, BufferedReader> result = new HashMap<>(9);

  for (ZipEntry zipEntry = zipInputStream.getNextEntry(); zipEntry != null; zipEntry = zipInputStream.getNextEntry()) {

    if (zipEntry.isDirectory()) {

      continue;

    }

    result.put(zipEntry.getName(), new BufferedReader(new InputStreamReader(zipInputStream)));

  }

  return result;

}

同一类中的其他签名(调用相同的方法):


  public static Map<String, BufferedReader> unzipFile(String zippedFile) throws IOException {

    return unzipFile(new File(zippedFile));

  }


  public static Map<String, BufferedReader> unzipFile(File zippedFile) throws IOException {

    return unzipFile(new FileInputStream(zippedFile));

  }

我的想法是Map从该方法中获取返回的值,并能够在我的代码的其他地方读取它。问题是每次我在此方法的循环result.get("filename").readLine()外调用时,它都会返回.fornull


这是此方法的简单单元测试 - 目前在最后一个失败Assert.assertNotNull:


  @Test

  public void unzipFileTest() throws Exception  {

    Map<String, BufferedReader> result = FileHandlerUtility.unzipFile(TestUtil.FILE_SAMPLE_NAME);

    Assert.assertNotNull(result);

    Assert.assertEquals(result.size(), 9);

    Assert.assertNotNull(result.get("Car.txt"));

    Assert.assertNotNull(result.get("Client.txt"));

    Assert.assertNotNull(result.get("Client.txt").readLine());

  }

我想可能与创建的变量的范围有关,因为在调试时,我注意到我可以在for循环中获取文件的内容。但是,我不想将这种 zip 提取方法与获取内容并解析它的方法混合使用。此外,我不想将提取的文件保存到光盘并稍后重新打开它们。


那么,我怎样才能用不会在调用时返回 null 的 s 来填充Map它BufferedReader呢readLine?


慕码人2483693
浏览 303回答 1
1回答

浮云间

ZipInputStream每次迭代入口指针时,都会丢失入口指针,因为每个 ZipInputStream 对象只允许一个流。try (ZipInputStream is = new ZipInputStream(Zippy.class.getResourceAsStream("file.zip"))) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ZipEntry entry;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while ((entry = is.getNextEntry()) != null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!entry.isDirectory()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // do your logic here (get the entry name)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; is.closeEntry();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }来自javadocs:closeEntry() -Closes the current ZIP entry and positions the stream for reading the next entry.getNextEntry() - Reads the next ZIP file entry and positions the stream at the beginning of the entry data.基本上,您在任何给定时间只能打开一个条目。因此,如果你想做你正在做的事情,你能做的最好的就是保存 zip 条目的名称并遍历 ZipInputStream 以将指针移动到正确的位置,然后你可以使用 ZipInputStream.read() 来获取字节。压缩文件如果您可以使用 ZipFile 对象(而不是 ZipInputStream),您就可以做您想要完成的事情。&nbsp;static void loadMap() throws IOException {&nbsp; &nbsp; ZipFile file = new ZipFile("testzip.zip");&nbsp; &nbsp; Enumeration<? extends ZipEntry> entries = file.entries();&nbsp; &nbsp; while (entries.hasMoreElements()) {&nbsp; &nbsp; &nbsp; &nbsp; ZipEntry entry = entries.nextElement();&nbsp; &nbsp; &nbsp; &nbsp; if (!entry.isDirectory()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; streamMap.put(entry.getName(), new BufferedReader(new InputStreamReader(file.getInputStream(entry))));&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}public static void main(String[] args) throws IOException {&nbsp; &nbsp; loadMap();&nbsp; &nbsp; Iterator<BufferedReader> iter = streamMap.values().iterator();&nbsp; &nbsp; while (iter.hasNext()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; BufferedReader reader = iter.next();&nbsp; &nbsp; &nbsp; &nbsp; String line;&nbsp; &nbsp; &nbsp; &nbsp; while ((line = reader.readLine()) != null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(line);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}OUTPUT:file 2: First line!file 2: Second Line!file 1: First line!file 1 : Second Line!BUILD SUCCESSFUL (total time: 0 seconds)您只需要记住保存 zip 文件引用并file.close();在完成后调用。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java