package eu.openaire.urls_worker.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class FilesZipper { private static final Logger logger = LoggerFactory.getLogger(FilesZipper.class); public static File zipMultipleFilesAndGetZip(long assignmentsCounter, int zipBatchCounter, List filesToZip, String baseDirectory) { String zipFilename = baseDirectory + "assignments_" + assignmentsCounter + "_full-texts_" + zipBatchCounter + ".zip"; // For example: assignments_2_full-texts_4.zip | where < 4 > is referred to the 4th batch of files requested by the controller. int numZippedFiles = 0; File zipFile = new File(zipFilename); try ( ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(zipFile.toPath()), StandardCharsets.UTF_8) ) { for ( String file : filesToZip ) { if ( zipAFile(file, zos, baseDirectory) ) numZippedFiles ++; } } catch (Exception e) { logger.error("Exception when creating the zip-file: " + zipFilename, e); return null; } logger.debug("Zipped " + numZippedFiles + " files for assignments_" + assignmentsCounter + ", batch_" + zipBatchCounter); return zipFile; } private static boolean zipAFile(String fileName, ZipOutputStream zos, String baseDir) { boolean shouldCloseEntry = false; // Useful in order to know if we should close the entry (an Exception may appear, and so we should not try to close it). String fullFileName = baseDir + fileName; try (FileInputStream fis = new FileInputStream(fullFileName)) { zos.putNextEntry(new ZipEntry(fileName)); shouldCloseEntry = true; int readByte; while ( (readByte = fis.read()) != -1 ) { zos.write(readByte); } } catch (FileNotFoundException fnfe) { logger.error("Error zipping file: " + fullFileName, fnfe.getMessage()); return false; } catch (Exception e) { if ( ! e.getMessage().contains("duplicate") ) logger.error("Error zipping file: " + fullFileName, e); return false; } finally { if ( shouldCloseEntry ) { try { zos.closeEntry(); // close the entry here (not the ZipOutputStream) } catch (IOException e) { logger.error("", e); } } } return true; } }