Apache foundation by default comes with lots and lots of utilities for us to use. In most of the cases we are kind of unaware of the utility which exists for use to use in our production environment.
In this tutorial we will go over one of the utility by which we could compress any file or directory programmatically in Java. In other words simple archives utility.
Why we need this utility?
Sometime back I’ve written an article on how to upload files using Spring MVC architecture. If you have very big file and you are hosting other users file in some of the file system like netapp or filer or etc then you may want to compress files before upload. You could marry below code into your application to achieve same purpose.
Let’s checkout a result first to better understand:
Before:
After:
Let’s get started:
- Create class
CrunchifyCompressArchivesUtility.java
- Add below maven dependency to your project.
- If you don’t have maven project then follow these steps.
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId> <version>1.9</version> </dependency>
- We are going to use Apache Commons
compress archivers
utility TarArchiveEntry
class represents an entry in a Tar archive. It consists of the entry’s header, as well as the entry’s File. Entries can be instantiated in one of three ways, depending on how they are to be used.TarArchiveOutputStream
class writes a UNIX tar archive as an OutputStream.- We will archive just a file first
- Also in the same program we will archive a directory
- We are going to convert file and directory to
.zip
file. If you want.tar
then just change code below. - Please change path in below code
package com.crunchify.tutorials; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; /** * @author Crunchify.com * */ public class CrunchifyCompressArchivesUtility { private static final String CRUNCHIFY_BASEDIR = ""; // Default output path private static final String CRUNCHIFY_PATH = "/Users/<username>/Desktop/"; // .zip or .tar as per need private static final String FILE_EXTENSION = ".zip"; public static void main(String[] args) { try { // Archive File crunchfyArchive("/Users/appshah/Desktop/crunchifyTarFile.txt"); log("Archive a file task completed...\n"); // Archive Directory crunchfyArchive("/Users/appshah/Desktop/crunchifyTarDirectory"); log("Archive a Directory task completed..."); } catch (Exception e) { log(e.getStackTrace().toString()); } } public static void crunchfyArchive(String srcPath) throws Exception { File crunchifySourceFile = new File(srcPath); // Returns the name of the file or directory denoted by this abstract pathname String crunchifyFileName = crunchifySourceFile.getName(); // Returns the pathname string of this abstract pathname's parent String crunchifyBaseFileNamePath = crunchifySourceFile.getParent(); String destPath = crunchifyBaseFileNamePath + File.separator + crunchifyFileName + FILE_EXTENSION; log("Archived Location: " + destPath); TarArchiveOutputStream outputStream = new TarArchiveOutputStream( new FileOutputStream(new File(destPath))); crunchfyArchive(crunchifySourceFile, outputStream, CRUNCHIFY_BASEDIR); // Flushes this output stream and forces any buffered output bytes to be written out outputStream.flush(); // Closes the underlying OutputStream outputStream.close(); } private static void crunchfyArchive(File crunchifySourceFile, TarArchiveOutputStream outputStream, String crunchifyBasePath) throws Exception { if (crunchifySourceFile.isDirectory()) { // Archive Directory archiveCrunchifyDirectory(crunchifySourceFile, outputStream, crunchifyBasePath); } else { // Archive File archiveCrunchifyFile(crunchifySourceFile, outputStream, crunchifyBasePath); } } private static void archiveCrunchifyDirectory(File crunchifyDirectory, TarArchiveOutputStream outputStream, String crunchifyBasePath) throws Exception { // Returns an array of abstract pathnames denoting the files in the directory denoted by this abstract pathname File[] crunchifyFiles = crunchifyDirectory.listFiles(); if (crunchifyFiles != null) { if (crunchifyFiles.length < 1) { // Construct an entry with only a name. This allows the programmer to construct the entry's header "by hand". File // is set to null TarArchiveEntry entry = new TarArchiveEntry( crunchifyBasePath + crunchifyDirectory.getName() + CRUNCHIFY_PATH); // Put an entry on the output stream outputStream.putArchiveEntry(entry); // Close an entry. This method MUST be called for all file entries that contain data outputStream.closeArchiveEntry(); } // Repeat for all files for (File crunchifyFile : crunchifyFiles) { crunchfyArchive(crunchifyFile, outputStream, crunchifyBasePath + crunchifyDirectory.getName() + CRUNCHIFY_PATH); } } } private static void archiveCrunchifyFile(File crunchifyFile, TarArchiveOutputStream outputStream, String crunchifyDirectory) throws Exception { TarArchiveEntry crunchifyEntry = new TarArchiveEntry( crunchifyDirectory + crunchifyFile.getName()); // Set this entry's file size crunchifyEntry.setSize(crunchifyFile.length()); outputStream.putArchiveEntry(crunchifyEntry); BufferedInputStream inputStream = new BufferedInputStream( new FileInputStream(crunchifyFile)); int counter; // 512: buffer size byte byteData[] = new byte[512]; while ((counter = inputStream.read(byteData, 0, 512)) != -1) { outputStream.write(byteData, 0, counter); } inputStream.close(); outputStream.closeArchiveEntry(); } // Crunchify's favorite log utility private static void log(String string) { System.out.println(string); } }
Output
Archived Location: /Users/<username>/Desktop/crunchifyTarFile.txt.zip Archive a file task completed... Archived Location: /Users/<username>/Desktop/crunchifyTarDirectory.zip Archive a Directory task completed...