5

Summary: Having the byte image of a.zip that contains a.txt, how can I get a clean and correct reader that returns lines of the text file?

I do download the image of a zip file from a web service into the byte[] content. I would like to write a method like

private BufferedReader contentToBufferedReader(byte[] content)

that would return a reader that can be used like

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

So far, I have (updated)

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

I am not sure how to close all of the stream object when something fails. Moreover, I am not sure how to close them if the reader was successfully returned, used, and closed.

pepr
  • 20,112
  • 15
  • 76
  • 139
  • 2
    possible duplicate of [Reading text files in a zip archive](http://stackoverflow.com/questions/4473256/reading-text-files-in-a-zip-archive) – Modus Tollens Oct 08 '13 at 11:04
  • Thanks, Katja, for the hint on how to decorate the `zipStream`. I have modified the question, so that it should not be considered a duplicate of the question you had mentioned. – pepr Oct 08 '13 at 11:55

2 Answers2

1

Check this topic, you will probably need to unzip file first, and than you can read it.

What is a good Java library to zip/unzip files?

Community
  • 1
  • 1
Drake29a
  • 896
  • 8
  • 23
  • +1 for the link. I have found the `zip4j` could be a good alternative to the Android standard zip support. It seems that the zip image I get uses zip64, that is not supported by the `ZipInputStream`. – pepr Oct 08 '13 at 12:02
1

This will get the bytes out all in one go (uses guava ByteStreams for convenience)

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

you can get a reader like this:

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

The zipStream advances when you call zipStream.getNextEntry(). I also think the stream doesn't support mark and reset iirc, which means you only get to read it once (hence the get it all out at once before passing it to other processing that may need random access)

tom
  • 2,704
  • 16
  • 28
  • +1 Thanks for teaching me the `entry.isDirectory()`. Otherwise, I prefer not to extract the content of `zipStream` to `byte[]` if I can avoid it. Also, I would prefer to call `zipStream.getNextEntry()` only at one place -- in the `while` condition. – pepr Oct 08 '13 at 12:40
  • Glad to help. Note that even if you don't pull all the bytes out at once, make sure you only read from them once. I had nightmares discovering that. – tom Oct 08 '13 at 12:42