File Compression Utility in Java Spring Boot

File Compression in Java Spring Boot

Niket Agrawal
4 min readJul 2, 2023

Do you know that optimizing the disk space on file servers is one of the most crucial non-functional requirements for Java applications? If managed wisely, it can lead to 60% to 70% cost savings on file storage servers. Hence, it becomes quite crucial to zip the data files produced by Java Spring Boot APIs.

This article is useful if you work with any Java Spring Boot API that is producing or exporting huge amounts of data files on the storage server. If you follow this approach and propose it as an improvement solution, I assure you will get cherry points from your clients for optimizing their Java Spring Boot API.

Java has multiple libraries that help us zip the content, and it also provides native file operations to zip the data files. We will use the native approach to achieve this.

Let us create a utility that can be bundled anywhere in Java code. It can be used anywhere within your microservice. One can also put this in a shared library and expose it as a utility across all the microservices in your organization. Our utility will have two functionalities.

1) Zip the given source file

2) It can also delete the original file after compression is successful

Prerequisites:

JDK ≥ 1.8 + Maven > 3.X + Spring Boot 2.X + Lombok + Common-IO

Let's create an object that will have basic parameters to zip the file. As you can see below, I have created the FileZipper class, which has Builder and Getter functionality through Lombok.

@Builder(setterPrefix = "set")
@Getter
public class FileZipper {

@NonNull
private String sourceFilePath;
@NonNull
private String sourceFileName;
@NonNull
private String sourceFileExtension;
@NonNull
private String zippedFilePath;
@NonNull
private String zippedFileName;
private boolean deleteSourceAfterZipped;
}

Let us now create a Java service class named FileZippingService that will zip the source file as per user input. This service class also has file deletion functionality, which can delete the source file after file compression is successful.

public class FileZippingService {

private static final String DOT = ".";
private static final String ZIP = ".zip";

private FileZippingService() {
}

static Logger logger = LoggerFactory.getLogger(FileZippingService.class);

/**
* Method to Zip a file
*
* @param fileZipper
*/
public static void zipExportFile(FileZipper fileZipper) {

String sourceFileWithPath = fileZipper.getSourceFilePath().concat(fileZipper.getSourceFileName()).concat(DOT)
.concat(fileZipper.getSourceFileExtension());
String zippedFileWithPath = fileZipper.getZippedFilePath().concat(fileZipper.getZippedFileName()).concat(ZIP);
logger.info("Source File : {} will be zipped into {}", sourceFileWithPath, zippedFileWithPath);
try {
File fileToZip = new File(sourceFileWithPath);
if (fileToZip.exists()) {
FileOutputStream fos = new FileOutputStream(zippedFileWithPath);
ZipOutputStream zipOut = new ZipOutputStream(fos);
FileInputStream fis = new FileInputStream(fileToZip);
ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
zipOut.putNextEntry(zipEntry);
byte[] bytes = new byte[1024];
int length;
while ((length = fis.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
zipOut.close();
fis.close();
fos.close();
logger.info("{} zipped successfully at {}", sourceFileWithPath, zippedFileWithPath);
if (fileZipper.isDeleteSourceAfterZipped())
deleteFile(sourceFileWithPath);
}
} catch (IOException e) {
logger.error("Error while Zipping the file", e);
deleteFile(zippedFileWithPath);
}

}

/**
* Method to delete a file at given path
*
* @param fileToDelete
*/
private static void deleteFile(String fileToDelete) {
File filetoDelete = new File(fileToDelete);
if (filetoDelete.exists()) {
if (FileUtils.deleteQuietly(filetoDelete)) {
logger.info("{} deleted successfully.", fileToDelete);
} else {
logger.info("{} deletion unsuccessfull.", fileToDelete);
}
} else {
logger.info("{} was not found for deletion.", fileToDelete);
}

}

}

Let us now test the code by running the spring boot application. As one can see in the below Java file, I have provided the source path from where the file needs to be read, the name, and the extension of the source file. I have provided the file name of the compressed file and the path where it needs to be stored after compression. I have also set the flag that will decide whether to delete the source file after compression or not.

@SpringBootApplication
public class FileZippingApplication {

public static void main(String[] args) {
SpringApplication.run(FileZippingApplication.class, args);

FileZipper fileZipper = FileZipper.builder()
.setSourceFilePath("C:/Data/")
.setSourceFileName("UserData")
.setSourceFileExtension("xlsx")
.setZippedFileName("ZippedUserData")
.setZippedFilePath("C:/Data/")
.setDeleteSourceAfterZipped(true)
.build();

FileZippingService.zipExportFile(fileZipper);
}

}

Furthermore, I was amazed to see the performance of this piece of code. In one of our business applications, we had large CSV files. Their general size was between 600 MB and 1 GB, and it was causing a lot of disc space consumption as we got over 1000 requests in an hour.

I was amazed to see the outcome of the above code; it reduced disk size by 85% after file compression, and we even were able to publish files via email to customers. This is a perfect example of how a small piece of code can save thousands of Dollars.

Please follow my profile, Niket Agrawal for future articles and share this article if you find it informative. Reference URLs are available below

Code Reference: https://github.com/niket17590/java-springboot-tutorials/tree/master/file-zipping

LinkedIn: https://www.linkedin.com/in/niketagrawal

GitHub: https://github.com/niket17590

Spring Boot Articles by Niket Agrawal

--

--

Niket Agrawal

Java Spring Boot backend developer with around 10 years of IT MNC experience