Vlad
Vlad

Reputation: 93

Zip ByteArray decompression returns null but input stream is valid

So i am trying to zip a csv file in memory, store it as a BLOB in MYSQL and then fetch and decompress it, but the ZipInputStream.getEntry returns null and i really can't decompress the file, i tried everything and i really can't find the answer. First time i compressed/decompressed the file using GZIP and worked, but it altered the CSV file structure so thats why i am trying with Zip. The CSV file is recieved from the front end via Spring's MultipartFile.getBytes().

Here is the compressed file header seen from DB (The header seems valid)

00000000  50 4B 03 04 14 00 08 08 08 00 B4 A0 8F 50 00 00    PK........´ .P..

Thanks in advance!

The compression method:

@Throws(Exception::class)
fun compressFile(file : ByteArray) : ByteArray {
    val baos = ByteArrayOutputStream()
    val zos = ZipOutputStream(baos)
    val entry = ZipEntry("data.csv")
    entry.size = file.size.toLong()
    zos.putNextEntry(entry)
    zos.write(file)
    zos.closeEntry()
    zos.close()
    return baos.toByteArray()
}

The decompression method:

@Throws(Exception::class)
fun decompressFile(file : ByteArray): ByteArray {
   if (file.isEmpty()) return file
   val gis = ZipInputStream(ByteArrayInputStream(file))
   val bf = BufferedReader(InputStreamReader(gis, "UTF-8"))
   var outStr = ""
   var line: String
   while (bf.readLine().also { line = it ?: "" } != null) {
       outStr += line
   }
   gis.close()
   bf.close()
   return outStr.toByteArray()
}

The ZipInputStream object after init

Upvotes: 0

Views: 409

Answers (1)

Andreas
Andreas

Reputation: 159155

To read a ZipInputStream, you must call getNextEntry() before reading.

For this example, I created a zip file with 2 files:

  • foo.text with content Foo Bar
  • hello.txt with content Hello World

Here is code to show that attempting to read before calling getNextEntry() will yield nothing:

public static void main(String[] args) throws Exception {
    try (ZipInputStream zip = new ZipInputStream(new FileInputStream("C:\\Temp\\foo.zip"))) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(zip, "UTF-8"));

        // read before getNextEntry() finds nothing
        printText(reader);

        ZipEntry zipEntry;
        while ((zipEntry = zip.getNextEntry()) != null) {
            System.out.println("Entry Name: " + zipEntry.getName() + "   Size: " + zipEntry.getSize());

            // read after getNextEntry() finds only the entry's content
            printText(reader);
        }
    }
}
static void printText(BufferedReader reader) throws IOException {
    int count = 0;
    for (String line; (line = reader.readLine()) != null; count++)
        System.out.println("  " + line);
    System.out.println(count + " lines");
}

Output

0 lines
Entry Name: foo.txt   Size: 7
  Foo Bar
1 lines
Entry Name: hello.txt   Size: 11
  Hello World
1 lines

Upvotes: 2

Related Questions