-1

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.

pavel_orekhov
  • 1,657
  • 2
  • 15
  • 37
  • What have you tried so far? It shouldn't take long to test your guess. – Jim Garrison Jul 04 '22 at 22:25
  • I literally wrote the only option I came up with in the first paragraph. Is there a more elegant way? – pavel_orekhov Jul 04 '22 at 22:26
  • Does that option work? Does it work on windows where file locking rules are different? – tgdavies Jul 04 '22 at 22:43
  • You may straight-up not be able to do this. You'll have to figure out an alternate approach. – Louis Wasserman Jul 04 '22 at 22:59
  • @LouisWasserman found an answer. Thanks. – pavel_orekhov Jul 04 '22 at 23:07
  • You don't. It is a serial medium. You can't do this, unless you're prepared to load the whole thing into memory, which is hardly the point of ZIP. – user207421 Jul 05 '22 at 00:44
  • @user207421 yes you can, i just showed it – pavel_orekhov Jul 05 '22 at 01:01
  • I suspect the best approach would be to pass in a callable object to the method which traverses the ZipInputStream, and have that method invoke the callable for each zip entry. That callable object could be a java.util.concurrent.Callable, or it could be an implementation of a custom functional interface with a method like `void processZipEntry(InputStream entryStream) throws IOException;`. – VGR Jul 05 '22 at 10:58

1 Answers1

0

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

pavel_orekhov
  • 1,657
  • 2
  • 15
  • 37