Четец за получаване на текстови редове от компресиран текстов файл

Резюме: Имайки байтово изображение на a.zip, което съдържа a.txt, как мога да получа чист и правилен четец, който връща редове от текстовия файл?

Изтеглям изображението на zip файл от уеб услуга в byte[] content. Бих искал да напиша метод като

private BufferedReader contentToBufferedReader(byte[] content)

това ще върне четец, който може да се използва като

reader = contentToBufferedReader(content);
while ((line = reader.readLine()) != null) {
    processThe(line);
}
reader.close()

Досега имам (актуализиран)

private BufferedReader contentToBufferedReader(byte[] content) {

    ByteArrayInputStream bais = new ByteArrayInputStream(content);
    ZipInputStream zipStream = new ZipInputStream(bais);
    BufferedReader reader = null;

    try {
        ZipEntry entry = zipStream.getNextEntry();

        // I need only the first (and the only) entry from the zip file.
        if (entry != null) {
            reader = new BufferedReader(new InputStreamReader(zipStream, "UTF-8"));
            System.out.println("contentToBufferedReader(): success");
        }
    }
    catch (IOException e) {
        System.out.println("contentToBufferedReader(): failed...");
        System.out.println(e.getMessage());
    }

    return reader;
}

Не съм сигурен как да затворя целия обект на потока, когато нещо се провали. Освен това не съм сигурен как да ги затворя, ако reader е успешно върнат, използван и затворен.


person pepr    schedule 08.10.2013    source източник
comment
възможен дубликат на Четене на текстови файлове в zip архив   -  person Modus Tollens    schedule 08.10.2013
comment
Благодаря, Катя, за съвета как да украся zipStream. Промених въпроса, така че да не се счита за дубликат на въпроса, който споменахте.   -  person pepr    schedule 08.10.2013


Отговори (2)


Това ще изведе всички байтове наведнъж (използва guava ByteStreams за удобство)

ZipEntry entry = zipStream.getNextEntry();
while (entry != null) {
  if (!entry.isDirectory()) {
    String filename = entry.getName();//this includes the path!
    byte[] data = ByteStreams.toByteArray(zipStream);
    //do something with the bytes 
  }
  entry = zipIn.getNextEntry();
}

можете да получите четец като този:

InputStreamReader reader = new InputStreamReader(new ByteArrayInputStream(data)));

ZipStream напредва, когато извикате zipStream.getNextEntry(). Също така мисля, че потокът не поддържа маркиране и нулиране на iirc, което означава, че можете да го прочетете само веднъж (следователно го изваждайте наведнъж, преди да го предадете на друга обработка, която може да се нуждае от произволен достъп)

person tom    schedule 08.10.2013
comment
+1 Благодаря, че ме научихте на entry.isDirectory(). В противен случай предпочитам да не извличам съдържанието от zipStream до byte[], ако мога да го избегна. Освен това бих предпочел да извикам zipStream.getNextEntry() само на едно място -- в условието while. - person pepr; 08.10.2013
comment
Радвам се да помогна. Имайте предвид, че дори и да не изтеглите всички байтове наведнъж, уверете се, че ги четете само веднъж. Сънувах кошмари, откривайки това. - person tom; 08.10.2013

Вижте тази тема, вероятно първо ще трябва да разархивирате файла и след това можете да го прочетете.

Коя е добра библиотека на Java за компресиране/разархивиране на файлове?

person Drake29a    schedule 08.10.2013
comment
+1 за линка. Открих, че zip4j може да бъде добра алтернатива на стандартната поддръжка на zip на Android. Изглежда, че zip изображението, което получавам, използва zip64, който не се поддържа от ZipInputStream. - person pepr; 08.10.2013