Skip to content

Instantly share code, notes, and snippets.

@xyznaveen
Created March 14, 2021 09:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xyznaveen/8f6eb525c23f3a9b816f60285f188a92 to your computer and use it in GitHub Desktop.
Save xyznaveen/8f6eb525c23f3a9b816f60285f188a92 to your computer and use it in GitHub Desktop.
Java zip compression example
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Stack;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipHelper {
public static final int BUFFER_SIZE = 1024 * 8;
public static final int EOF = -1;
public static final int OFFSET_START = 0;
public static final int SUBSTRING_OFFSET = 1;
public static final String EMPTY = "";
private final File source;
private final ZipOutputStream zipOutputStream;
private final Stack<File> stackOfFilesToBeZipped;
public ZipHelper(File source, File destination) throws FileNotFoundException {
// the source file and the destination file
// can be a single file or a directory
this.source = source;
final FileOutputStream fileOutputStream = new FileOutputStream(destination);
zipOutputStream = new ZipOutputStream(fileOutputStream);
// the level of compression can be either of 2; ZipEntry.STORED or ZipEntry.DEFLATED
zipOutputStream.setLevel(ZipEntry.STORED);
// optional if you want to add comment to the zip file
// zipOutputStream.setComment("don't forget to bookmark https://techenum.com");
stackOfFilesToBeZipped = new Stack<>();
// count total files to be zipped
recursivelyAddFilesToStack(source);
System.out.println("there are " + stackOfFilesToBeZipped.size() + " files to be zipped.");
}
/**
* Start the zip operation.
*
* @throws IOException
*/
public void zip() throws IOException {
while (true) {
// looks like we have completed our zipping task
if (stackOfFilesToBeZipped.empty()) {
zipOutputStream.close();
break;
}
// pop file from satck and add to zip
zipFile(stackOfFilesToBeZipped.pop());
}
}
/**
* This method recursively checks if the file is a directory or a file.
* We only need the files so ignores the directory if encountered any.
*
* @param file the file to be added to stack
*/
private void recursivelyAddFilesToStack(File file) {
if (file.isFile()) {
stackOfFilesToBeZipped.add(file);
return;
}
File[] files = file.listFiles();
if (files == null) {
// directory is empty
return;
}
for (File item : files) {
recursivelyAddFilesToStack(item);
}
}
/**
* Zip a single file appropriately into the destination zip file.
*
* @param file the file that should be zipped.
* @throws IOException
*/
private void zipFile(File file) throws IOException {
String relativePath = file.getAbsolutePath().replace(source.getAbsolutePath(), EMPTY);
if (relativePath.isEmpty()) {
// relativePath will be empty for a single file
// so to fix that we must add only that file's filename
relativePath = source.getName();
} else {
// we do not want the forward slash /
// so for all other path we have to trim out the first character i.e. /
relativePath = relativePath.substring(SUBSTRING_OFFSET);
}
ZipEntry zipEntry = new ZipEntry(relativePath);
zipOutputStream.putNextEntry(zipEntry);
// write the data to output file
final FileInputStream fileInputStream = new FileInputStream(file);
final byte[] buffer = new byte[BUFFER_SIZE];
int readBytes;
while (true) {
readBytes = fileInputStream.read(buffer);
if (readBytes == EOF) break;
zipOutputStream.write(buffer, OFFSET_START, readBytes);
}
fileInputStream.close();
zipOutputStream.closeEntry();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment