In Java: How to zip file from byte[] array?
You can use Java's java.util.zip.ZipOutputStream to create a zip file in memory. For example:
public static byte[] zipBytes(String filename, byte[] input) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry entry = new ZipEntry(filename);
entry.setSize(input.length);
zos.putNextEntry(entry);
zos.write(input);
zos.closeEntry();
zos.close();
return baos.toByteArray();
}
How can I convert byte array to ZIP file
To get the contents from the bytes you can use
ZipInputStream zipStream = new ZipInputStream(new ByteArrayInputStream(bytes));
ZipEntry entry = null;
while ((entry = zipStream.getNextEntry()) != null) {
String entryName = entry.getName();
FileOutputStream out = new FileOutputStream(entryName);
byte[] byteBuff = new byte[4096];
int bytesRead = 0;
while ((bytesRead = zipStream.read(byteBuff)) != -1)
{
out.write(byteBuff, 0, bytesRead);
}
out.close();
zipStream.closeEntry();
}
zipStream.close();
How to convert zip file into bytes in Java
You can read a file from disk into a byte[]
using
byte[] ba = java.nio.file.Files.readAllBytes(filePath);
This is available from Java 7.
How to convert a byte array to ZIP file and download it using Java?
I am presuming here that you want to write a byte array to a ZIP file. As the data sent is also a ZIP file and to be saved is also ZIP file, shouldn't be a problem.
Two steps are needed: save it on disk and return the file.
1) Save on disk part:
File file = new File(/path/to/directory/save.zip);
if (file.exists() && file.isDirectory()) {
try {
OutputStream outputStream = new FileOutputStream(new File(/path/to/directory/save.zip));
outputStream.write(bytes);
outputStream.close();
} catch (IOException ignored) {
}
} else {
// create directory and call same code
}
}
2) Now to get it back and download it, you need a controller :
@RequestMapping(value = "/download/attachment/", method = RequestMethod.GET)
public void getAttachmentFromDatabase(HttpServletResponse response) {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getFileName() + "\"");
response.setContentLength(file.length);
FileCopyUtils.copy(file as byte-array, response.getOutputStream());
response.flushBuffer();
}
I have edited the code I have, so you will have to make some changes before it suits you 100%. Let me know if this is what you were looking for. If not, I will delete my answer. Enjoy.
Writing a file from byte array into a zip file
Don't use a BufferedWriter
to write binary content! A Writer
is made to write text content.
Use that instead:
final Path zip = file.toPath();
final Map<String, ?> env = Collections.emptyMap();
final URI uri = URI.create("jar:" + zip.toUri());
try (
final FileSystem zipfs = FileSystems.newFileSystem(uri, env);
) {
Files.write(zipfs.getPath("into/zip"), buf,
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
}
(note: APPEND
is a guess here; it looks from your question that you want to append if the file already exists; by default the contents will be overwritten)
Java Zip File Created With ByteArrayOutputStream is smaller than with FileOutputStream
The following statement is wrong:
baos.writeTo(new FileOutputStream("TEST_AS_BYTESTREAM_1.zip"));
The javadoc of writeTo(OutputStream out)
does not say anything about closing the OutputStream
, which means it doesn't, so the last of the data is still sitting buffered in the un-closed, un-flushed FileOutputStream
.
The correct way is:
try (OutputStream out = new FileOutputStream("TEST_AS_BYTESTREAM_1.zip")) {
baos.writeTo(out);
}
Also, a ByteArrayOutputStream
does not need to be closed or flushed. As the javadoc of close()
says it:
Closing a
ByteArrayOutputStream
has no effect.
You will however need to call finish()
on an ZipOutputStream
to complete the content. Since closing the zip stream automatically finishes it for you, the correct way to do this is:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ZipOutputStream zipOS = new ZipOutputStream(baos)) {
// create the Zip file content here
}
try (OutputStream out = new FileOutputStream("TEST_AS_BYTESTREAM_1.zip")) {
baos.writeTo(out);
}
When writing directly to a file:
try (ZipOutputStream zipOS = new ZipOutputStream(new FileOutputStream("TEST_AS_FILE.zip"))) {
// create the Zip file content here
}
Consider adding a BufferedOutputStream
for better performance.
How to extract and read entries of zip file which is sent as a byte array
Seeing as the source is a byte[]
, you'll need to use a ByteArrayInputStream
to read the file.
public List<ZipEntry> extractZipEntries(byte[] content) throws IOException {
List<ZipEntry> entries = new ArrayList<>();
ZipInputStream zi = null;
try {
zi = new ZipInputStream(new ByteArrayInputStream(content));
ZipEntry zipEntry = null;
while ((zipEntry = zi.getNextEntry()) != null) {
entries.add(zipEntry);
}
} finally {
if (zi != null) {
zi.close();
}
}
return entries;
}
How can I write A map of byte Array into ZIP file
Change your code to:
ZipEntry entry = new ZipEntry(pair.getKey());
entry.setSize(pair.getValue().length);
zos.putNextEntry(entry);
zos.write(pair.getValue());
zos.flush();
You were writing zero bytes (int size = 0;
) out of an empty byte[]
(byte[] tmp = new byte[4 * 1024];
) rather than the bytes from the Map.
How to convert byte array to ZipOutputStream in spring MVC?
You have to copy the byte data (content) of the zip file to the output as well...
This should work (untested):
while ((ent = zipStream.getNextEntry()) != null) {
zipOutputStream.putNextEntry(ent);
// copy byte stream
org.apache.commons.io.IOUtils.copy(zis.getInputStream(ent), zipOutputStream);
}
BTW: why you do not just simply forward the original zip byte content?
try (InputStream is = new ByteArrayInputStream(fileData));) {
IOUtils.copy(is, response.getOutputStream());
}
or even better (thanks to comment by @M. Deinum)
IOUtils.copy(fileData, response.getOutputStream());
Related Topics
Java Fast Food Menu (Using Methods)
How a Jar File Can Read an External Properties File
Spring Boot Unsupported Media Type With @Requestbody
How to Handle JPA Unique Constraint Violations
Arraylist - How to Check If an Index Exists
How to Set Environment Variable or System Property in Spring Tests
Prevent Multiple Login Using the Same User Name and Password
How to Find an Object in an Arraylist by Property
How to Sort Date in Descending Order Using Comparator
How to Check Whether an Array Is Null/Empty
How to Replace a Placeholder in a String With a Simpledateformat Pattern
How to Mock Classes With Constructor Injection
How to Have Empty Requestparam Values Use the Defaultvalue
How to Return a Select Query from JPA Repository With Foreign Key Type