Search code examples
javazipjava-io

How do I get multiple InputStreams for each entry of a ZipInputStream, to read from those InputStreams later?


When we create a ZipInputStream z, we call getNextEntry on it and then read from z, in order to get the contents of the next file. I, however, need to get ZipInputStreams for those files to read from them later. How do I do that? Just create n ZipInputStreams, and call getNextEntry on the first one 1 time, on the second one 2 times, ..., on the nth one n times? Is there a more elegant way to do that than this?

I can't just read each entry into an array of bytes, because that will consume too much RAM, when the files are large and the max size of such a file can only be 2 gigs (we can't create byte[] arrays larger than that in Java), but I have larger files.


Solution

  • Wrote this (it's in scala though, because I use scala, not Java.

    import java.io.{FileInputStream, InputStream}
    import java.util.Scanner
    import java.util.zip.{ZipEntry, ZipFile, ZipInputStream}
    import scala.collection.mutable.ListBuffer
    
    object ZipTest {
      def main(args: Array[String]): Unit = {
        val zipFile = new ZipFile("/path/to/file")
        val entries = zipFile.entries()
        val listBuffer = new ListBuffer[InputStream]
        while (entries.hasMoreElements) {
          val entry = entries.nextElement()
          if(!entry.isDirectory) {
            val stream = zipFile.getInputStream(entry)
            listBuffer.addOne(stream)
          }
        }
        // small usage example
        var scanner = new Scanner(listBuffer(2))
        while(scanner.hasNextLine){
          println(scanner.nextLine())
        }
    
        scanner = new Scanner(listBuffer(0))
        while(scanner.hasNextLine){
          println(scanner.nextLine())
        }
      }
    }
    

    I actually found this approach in the top answer from here: Read Content from Files which are inside Zip file