Zwakele Mgabhi
Zwakele Mgabhi

Reputation: 387

create zip file without writing to disk

I am working on a Springboot application that has to return a zip file to a frontend when the user downloads some report. I want to create a zip file without writing the zip file or the original files to disk.

The directory I want to zip contains other directories, that contain the actual files. For example, dir1 has subDir1 and subDir2 inside, subDir1 will have two file subDir1File1.pdf and subDir1File2.pdf. subDir2 will also have files inside.

I can do this easily by creating the physical files on the disk. However, I feel it will be more elegant to return these files without writing to disk.

Upvotes: 2

Views: 1429

Answers (3)

Mick
Mick

Reputation: 973

Please note that you should stream whenever possible. In your case, you could write your data to https://docs.oracle.com/javase/8/docs/api/index.html?java/util/zip/ZipOutputStream.html.

The only downside of this appproach is: the client won't be able to show a download status bar, because the server will not be able to send the "Content-length" header. That's because the size of a ZIP file can only be known after it has been generated, but the server needs to send the headers first. So - no temporary zip file - no file size beforehand.

You are also talking about subdirectories. This is just a naming issue when dealing with a ZIP stream. Each zip item needs to be named like this: "directory/directory2/file.txt". This will produce subdirectories when unzipping.

Upvotes: 0

Rimjhim Doshi
Rimjhim Doshi

Reputation: 69

You can use following snippet :

public static byte[] zip(final String str) throws IOException {

        if (StringUtils.isEmpty(str)) {
            throw new IllegalArgumentException("Cannot zip null or empty string");
        }

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (GZIPOutputStream gos = new GZIPOutputStream(bos)) {
            gos.write(str.getBytes(StandardCharsets.UTF_8));
        }
        return bos.toByteArray();

    }

But as stated in another answer, make sure you are not risking your program too much by loading everything into your java memory.

Upvotes: 2

Neil
Neil

Reputation: 5780

You would use ByteArrayOutputStream if the scope was to write to memory. In essence, the zip file would be entirely contained in memory, so be sure that you don't risk to have too many requests at once and that the file size is reasonable in size! Otherwise this approach can seriously backfire!

Upvotes: 6

Related Questions