简体   繁体   中英

Write multiple Zip files to an OutputStream using IOUtils.copy method

This question feels very difficult to explain to me but ill do my best.

Currently I have a method that returns an InputStream with a Zip file that i have to add to a main zip file. Problem is when I write something into the OutputStream it overwrites previous written data. I tried using ZipOutputStream with ZipEntries but this recompresses the file and does weird things, so its not a solution. Things that I'm required to use and are not negotiable are:

  • Retrieving the file with the method that returns an InputStream

  • Using IOUtils.copy() method to download the file (this may be optional if u have another solution that allows me to download the file through a browser)

This is the code so far:

OutputStream os = null;
InputStream is = null;      
        
try {
    os = response.getOutputStream();
    for (int i = 0; i < splited.length; i += 6) {
        String[] file= //an array with the data to retrieve the file
        is = FileManager.downloadFile(args);
                    
        int read;
        byte[] buffer = new byte[1024];
        while (0 < (read = is.read(buffer))) {
                        
            os.write(buffer, 0, read);
        }
    }
} catch (Exception ex) {
    //Exception captures
} 

response.setHeader("Content-Disposition", "attachment; filename=FileName");
response.setContentType("application/zip");

        
IOUtils.copy(is, os);

os.close();
is.close();
        
return forward;

You can use ZipOutputStream wrapping the response's OutputStream but instead of close call finish, and do not call close on the ResponseOutputStream.

You must start with the HTTP headers.

response.setHeader("Content-Disposition", "attachment; filename=FileName");
response.setContentType("application/zip");
try {
    ZipOutputStream os = new ZipOutputStream(response.getOutputStream());
    for (int i = 0; i < splited.length - 5; i += 6) {
        String[] file= //an array with the data to retrieve the file
        try (InputStream is = FileManager.downloadFile(args)) {               
            os.putNextEntry(new ZipEntry(filePath));
            is.TransferTo(os);
            os.closeEntry();
        }
    }
    os.finish();
} catch (Exception ex) {
    //Exception captures
} 
return forward;

Since java 9 transferTo copies Input/OutputStreams. One can also copy a Path with Files.copy(Path, OutputStream) where Path is an URI based generalisation of File , so also URLs might immediately be copied.

Here try-with-resources ensures that every is is closed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM