How to Create a Zip File in Java

How to create a zip file in Java

Look at this example:

StringBuilder sb = new StringBuilder();
sb.append("Test String");

File f = new File("d:\\test.zip");
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(f));
ZipEntry e = new ZipEntry("mytext.txt");
out.putNextEntry(e);

byte[] data = sb.toString().getBytes();
out.write(data, 0, data.length);
out.closeEntry();

out.close();

This will create a zip in the root of D: named test.zip which will contain one single file called mytext.txt. Of course you can add more zip entries and also specify a subdirectory like this:

ZipEntry e = new ZipEntry("folderName/mytext.txt");

You can find more information about compression with Java here.

Creating zip archive in Java

// simplified code for zip creation in java

import java.io.*;
import java.util.zip.*;

public class ZipCreateExample {

public static void main(String[] args) throws Exception {

// input file
FileInputStream in = new FileInputStream("F:/sometxt.txt");

// out put file
ZipOutputStream out = new ZipOutputStream(new FileOutputStream("F:/tmp.zip"));

// name the file inside the zip file
out.putNextEntry(new ZipEntry("zippedjava.txt"));

// buffer size
byte[] b = new byte[1024];
int count;

while ((count = in.read(b)) > 0) {
out.write(b, 0, count);
}
out.close();
in.close();
}
}

how to zip a folder itself using java

It can be easily solved by package java.util.Zip no need any extra Jar files

Just copy the following code and run it with your IDE

//Import all needed packages
package general;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipUtils {

private List <String> fileList;
private static final String OUTPUT_ZIP_FILE = "Folder.zip";
private static final String SOURCE_FOLDER = "D:\\Reports"; // SourceFolder path

public ZipUtils() {
fileList = new ArrayList < String > ();
}

public static void main(String[] args) {
ZipUtils appZip = new ZipUtils();
appZip.generateFileList(new File(SOURCE_FOLDER));
appZip.zipIt(OUTPUT_ZIP_FILE);
}

public void zipIt(String zipFile) {
byte[] buffer = new byte[1024];
String source = new File(SOURCE_FOLDER).getName();
FileOutputStream fos = null;
ZipOutputStream zos = null;
try {
fos = new FileOutputStream(zipFile);
zos = new ZipOutputStream(fos);

System.out.println("Output to Zip : " + zipFile);
FileInputStream in = null;

for (String file: this.fileList) {
System.out.println("File Added : " + file);
ZipEntry ze = new ZipEntry(source + File.separator + file);
zos.putNextEntry(ze);
try {
in = new FileInputStream(SOURCE_FOLDER + File.separator + file);
int len;
while ((len = in .read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
} finally {
in.close();
}
}

zos.closeEntry();
System.out.println("Folder successfully compressed");

} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
zos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

public void generateFileList(File node) {
// add file only
if (node.isFile()) {
fileList.add(generateZipEntry(node.toString()));
}

if (node.isDirectory()) {
String[] subNote = node.list();
for (String filename: subNote) {
generateFileList(new File(node, filename));
}
}
}

private String generateZipEntry(String file) {
return file.substring(SOURCE_FOLDER.length() + 1, file.length());
}
}

Refer mkyong..I changed the code for the requirement of current question

Create a Zip File in Memory

Use ByteArrayOutputStream with ZipOutputStream to accomplish the task.

you can use ZipEntry to specify the files
to be included into the zip file.

Here is an example of using the above classes,

String s = "hello world";

ByteArrayOutputStream baos = new ByteArrayOutputStream();
try(ZipOutputStream zos = new ZipOutputStream(baos)) {

/* File is not on the disk, test.txt indicates
only the file name to be put into the zip */
ZipEntry entry = new ZipEntry("test.txt");

zos.putNextEntry(entry);
zos.write(s.getBytes());
zos.closeEntry();

/* use more Entries to add more files
and use closeEntry() to close each file entry */

} catch(IOException ioe) {
ioe.printStackTrace();
}

now baos contains your zip file as a stream

How to zip the content of a directory in Java

So, if I understand correctly, what you want is, instead of the target folder appearing in the Zip file, all the files within it should start at "/" in the Zip file.

For example, if you had

FolderToZip/
TestFile1.txt
TestFile2.txt
TestFile3.txt
SomeSubFolder/
TestFile4.txt
TestFile5.txt
TestFile6.txt

The contents of the Zip file should contain

TestFile1.txt
TestFile2.txt
TestFile3.txt
SomeSubFolder/
TestFile4.txt
TestFile5.txt
TestFile6.txt

To do this, you need to keep a reference to the "start" folder and strip it's path off the files you are adding, to create the ZipEntry.

For simplicity, I changed your code to support File instead of String, it just makes the whole thing a lot less messy.

But the magic appears here...

FileInputStream in = new FileInputStream(srcFile);
String name = srcFile.getPath();
name = name.replace(rootPath.getPath(), "");
System.out.println("Zip " + srcFile + "\n to " + name);
zip.putNextEntry(new ZipEntry(name));

rootPath is the initial folder (C:\\Drive\\temp\\testZip" in your example), srcFile is the file to be added.

Runnable example...

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipFolder {

public ZipFolder() {
}

public static void main(String[] args) throws Exception {
ZipFolder obj = new ZipFolder();
obj.zipFolder(new File("/Users/shanewhitehead/exports"),
new File("FolderZiper.zip"));
}

public void zipFolder(File srcFolder, File destZipFile) throws Exception {
try (FileOutputStream fileWriter = new FileOutputStream(destZipFile);
ZipOutputStream zip = new ZipOutputStream(fileWriter)) {

addFolderToZip(srcFolder, srcFolder, zip);
}
}

private void addFileToZip(File rootPath, File srcFile, ZipOutputStream zip) throws Exception {

if (srcFile.isDirectory()) {
addFolderToZip(rootPath, srcFile, zip);
} else {
byte[] buf = new byte[1024];
int len;
try (FileInputStream in = new FileInputStream(srcFile)) {
String name = srcFile.getPath();
name = name.replace(rootPath.getPath(), "");
System.out.println("Zip " + srcFile + "\n to " + name);
zip.putNextEntry(new ZipEntry(name));
while ((len = in.read(buf)) > 0) {
zip.write(buf, 0, len);
}
}
}
}

private void addFolderToZip(File rootPath, File srcFolder, ZipOutputStream zip) throws Exception {
for (File fileName : srcFolder.listFiles()) {
addFileToZip(rootPath, fileName, zip);
}
}
}

I also cleaned up your resource management, using try-with-resources

How to create a very specific zip file structure using Java

I hate guessing without being able to verify my assumptions, thus the comment/question about the availability of the actual server-side file checker on the FTP server, but for what it is worth and just assuming that the checker prefers STORED entries to DEFLATED ones, here is how you can create

  • deflated ZIP files from XML files (which makes sense because XML is nicely compressible) and
  • stored ZIP files from nested ZIP files (which also makes sense because usually compressed files cannot effectively get smaller when re-compressing them).

The problem here is that when using STORED entries it is mandatory to also set (un-)compressed size and CRC for each entry. This is how you can do it (unfortunately I am reading each nested ZIP file twice, once for calculating the CRC and once for copying its contents to the ZIP output stream):

Driver application:

package de.scrum_master.app;

import java.io.File;
import java.io.IOException;
import java.util.SortedMap;
import java.util.TreeMap;

public class Application {
public static void main(String[] args) throws IOException {
SortedMap<File, File[]> fileMappings = new TreeMap<>();
fileMappings.put(
new File("books.zip"),
new File[] { new File("books.xml") }
);
fileMappings.put(
new File("cds.zip"),
new File[] { new File("cds.xml") }
);
fileMappings.put(
new File("clothes.zip"),
new File[] { new File("clothes.xml") }
);

ZipTool zipTool = new ZipTool();
for (File zipFile : fileMappings.keySet())
zipTool.addToZip(zipFile, fileMappings.get(zipFile));
zipTool.addToZip(
new File("archive.zip"),
new File[] { new File("books.zip"), new File("cds.zip"), new File("clothes.zip") }
);
}
}

ZIP utility:

package de.scrum_master.app;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class ZipTool {
public void addToZip(File zipFile, File... filesToAdd) throws IOException {
try (
FileOutputStream fos = new FileOutputStream(zipFile.getAbsoluteFile());
ZipOutputStream zos = new ZipOutputStream(fos)
) {
final byte[] buffer = new byte[1024];
for (File fileToAdd : filesToAdd) {
ZipEntry entry = new ZipEntry(fileToAdd.getName());
if (fileToAdd.getName().endsWith(".zip")) {
entry.setMethod(ZipEntry.STORED);
long fileSize = fileToAdd.length();
entry.setSize(fileSize);
entry.setCompressedSize(fileSize);
CRC32 crc32 = new CRC32();
try (FileInputStream in = new FileInputStream(fileToAdd.getAbsoluteFile())) {
int len;
while ((len = in.read(buffer)) > 0) {
crc32.update(buffer, 0, len);
}
}
entry.setCrc(crc32.getValue());
}
zos.putNextEntry(entry);
try (FileInputStream in = new FileInputStream(fileToAdd.getAbsoluteFile())) {
int len;
while ((len = in.read(buffer)) > 0) {
zos.write(buffer, 0, len);
}
}
zos.closeEntry();
}
}
}
}

Maybe you can try that and provide me with feedback. If this is not good enough and the checker still complains, we can try something else to make the zip archives even more similar.

How to create a zip file and download it?

Within the line

ZipEntry anEntry = new ZipEntry(f.getPath());

you specify the path inside your zip file (i.e. f.getPath()). If you want a shorter path or none at all just manipulate this part (e.g. f.getName()).



Related Topics



Leave a reply



Submit