Issue
I have this Java code that creates and saves a zip file with a text file inside it:
public static void main(String[] args) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos)) {
String s = "Hello, world!";
ZipEntry entry = new ZipEntry("text_file.txt");
zos.putNextEntry(entry);
zos.write(s.getBytes());
zos.closeEntry();
try (OutputStream os = new FileOutputStream("zip_file.zip")) {
baos.writeTo(os);
System.out.println("ZIP file created successfully");
}
} catch (IOException e) {
System.out.println("Error: " + e);
}
}
The problem with this code is that it creates a zip file that is corrupted, so I cannot extract or even open the content within it.
Eventually I found out that if I manually close the ZipOutputStream
by putting zos.close()
after zos.closeEntry()
the zip file is created successfully without corruption. Honestly this does not make any sense to me since I have declared the ZipOutputStream
inside a try-with-resource statement, so I would have expected it to close automatically.
So it seems that the try-with-resource statement does not actually close the stream. Am I doing something wrong?
Any help would be appreciated.
OS: Windows 10
Note: I used ByteArrayOutputStream
because in the real scenario I have to create the zip file in memory, since I don't have a folder on a disk to rely on.
Solution
It turned out that I was misplacing the ByteArrayOutputStream
object: I should have not closed it by placing it inside the try-with-resource statement because, as explained here, ByteArrayOutputStream
is purely memory based so the allocated memory will be released automatically by the garbage collector.
The following code produces the desired result:
public static void main(String[] args) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zos = new ZipOutputStream(baos)) {
String s = "Hello, world!";
ZipEntry entry = new ZipEntry("text_file.txt");
zos.putNextEntry(entry);
zos.write(s.getBytes());
zos.closeEntry();
} catch (IOException e) {
System.out.println("Error: " + e);
}
try (OutputStream os = new FileOutputStream("zip_file.zip")) {
baos.writeTo(os);
System.out.println("ZIP file created successfully");
} catch (IOException e) {
System.out.println("Error: " + e);
}
}
Answered By - thwomp68
Answer Checked By - David Goodson (JavaFixing Volunteer)