Search code examples
scalazipcompression

Decompress a single file from a zip folder without writing in disk


Is it possible to decompress a single file from a zip folder and return the decompressed file without storing the data on the server?

I have a zip file with an unknown structure and I would like to develop a service that will serve the content of a given file on demand without decompressing the whole zip and also without writing on disk. So, if I have a zip file like this

zip_folder.zip
  |  folder1
       |  file1.txt
       |  file2.png
  |  folder 2
       |  file3.jpg
       |  file4.pdf
  |  ...

So, I would like my service to receive the name and path of the file so I could send the file.

For example, fileName could be folder1/file1.txt

 def getFileContent(fileName: String): IBinaryContent = {
    val content: IBinaryContent = getBinaryContent(...)

    val zipInputStream: ZipInputStream = new ZipInputStream(content.getInputStream)
    val outputStream: FileOutputStream = new FileOutputStream(fileName)

    var zipEntry: ZipEntry = null
    var founded: Boolean = false
    while ({
      zipEntry = zipInputStream.getNextEntry
      Option(zipEntry).isDefined && !founded
    }) {

      if (zipEntry.getName.equals(fileName)) {

        val buffer: Array[Byte] = Array.ofDim(9000) // FIXME how to get the dimension of the array
        var length = 0

        while ({
          length = zipInputStream.read(buffer)
          length != -1
        }) {
          outputStream.write(buffer, 0, length)
        }
        outputStream.close()
        founded = true
      }
    }

    zipInputStream.close()
    outputStream /* how can I return the value? */

  }

How can I do it without writing the content in the disk?


Solution

  • You can use a ByteArrayOutputStream instead of the FileOutputStream to uncompress the zip entry into memory. Then call toByteArray() on it.


    Also note that, technically, you would not even need to decompress the zip part if you can transmit it over a protocol (think: HTTP(S)) which supports the deflate encoding for its transport (which is usually the standard compression used in Zip files).