BufferedReader readLine возвращает ноль - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть 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() вне цикла for в этом методе, он возвращает null.

Вот простой модульный тест для этого метода, который в настоящее время не выполняется в последний 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. Однако я не хотел смешивать этот метод извлечения почтовых индексов с методом, который получает содержимое и анализирует его. Кроме того, я не хочу сохранять извлеченные файлы на диск и открывать их позже.

Итак, как я могу заполнить эти Map BufferedReader с, которые не будут возвращать ноль при readLine вызовах?

1 Ответ

1 голос
/ 17 апреля 2019

ZipInputStream

Каждый раз, когда вы повторяете указатель на запись, вы теряете указатель на запись, поскольку для каждого объекта ZipInputStream разрешен только один поток.

try (ZipInputStream is = new ZipInputStream(Zippy.class.getResourceAsStream("file.zip"))) {
            ZipEntry entry;
            while ((entry = is.getNextEntry()) != null) {
                if (!entry.isDirectory()) {
                    // do your logic here (get the entry name)
                }                
                is.closeEntry();
        }
    }

от 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 () чтобы получить байты.

Zip File

Если вы можете использовать объект ZipFile (вместо ZipInputStream), вы можете делать то, что пытаетесь выполнить.

 static void loadMap() throws IOException {
    ZipFile file = new ZipFile("testzip.zip");
    Enumeration<? extends ZipEntry> entries = file.entries();
    while (entries.hasMoreElements()) {
        ZipEntry entry = entries.nextElement();
        if (!entry.isDirectory()) {
            streamMap.put(entry.getName(), new BufferedReader(new InputStreamReader(file.getInputStream(entry))));
        }

    }

}

public static void main(String[] args) throws IOException {
    loadMap();

    Iterator<BufferedReader> iter = streamMap.values().iterator();
    while (iter.hasNext()) {            
        BufferedReader reader = iter.next();
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
    }
}


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();, когда вы закончите с этим.

...