118 lines
4.5 KiB
Java
Executable file
118 lines
4.5 KiB
Java
Executable file
package illgner.ch.createzip;
|
|
|
|
import illgner.ch.stream.OutputStreamEnhancer;
|
|
import org.apache.commons.io.IOUtils;
|
|
import org.apache.commons.io.output.CountingOutputStream;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import javax.crypto.NoSuchPaddingException;
|
|
import java.io.BufferedOutputStream;
|
|
import java.io.Closeable;
|
|
import java.io.File;
|
|
import java.io.FileOutputStream;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Path;
|
|
import java.nio.file.attribute.PosixFilePermission;
|
|
import java.security.InvalidAlgorithmParameterException;
|
|
import java.security.InvalidKeyException;
|
|
import java.security.NoSuchAlgorithmException;
|
|
import java.security.NoSuchProviderException;
|
|
import java.util.EnumSet;
|
|
import java.util.Set;
|
|
import java.util.zip.ZipEntry;
|
|
import java.util.zip.ZipOutputStream;
|
|
|
|
import static java.nio.file.attribute.PosixFilePermission.GROUP_READ;
|
|
import static java.nio.file.attribute.PosixFilePermission.OTHERS_READ;
|
|
import static java.nio.file.attribute.PosixFilePermission.OWNER_READ;
|
|
import static java.nio.file.attribute.PosixFilePermission.OWNER_WRITE;
|
|
|
|
public class SplitZipWriter implements Closeable {
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(SplitZipWriter.class);
|
|
|
|
private static final Set<PosixFilePermission> ZIP_FILE_PERMISSIONS = EnumSet.of(OWNER_READ, OWNER_WRITE, GROUP_READ, OTHERS_READ);
|
|
|
|
private final Path destinationDir;
|
|
private final String baseName;
|
|
private final int chunkSize;
|
|
private final int bufferSize;
|
|
private final ZipResult zipResult;
|
|
private OutputStreamEnhancer outputStreamEnhancer;
|
|
|
|
private ZipOutputStream zipOutputStream;
|
|
|
|
private int fileCount = 1;
|
|
private long bytesWritten = 0;
|
|
private File actualZipFile;
|
|
private CountingOutputStream countingOutputStream;
|
|
|
|
public SplitZipWriter(Path destinationDir, String baseName, int chunkSize, int bufferSize, OutputStreamEnhancer outputStreamEnhancer) {
|
|
this.destinationDir = destinationDir;
|
|
this.baseName = baseName;
|
|
this.chunkSize = chunkSize;
|
|
this.bufferSize = bufferSize;
|
|
this.zipResult = new ZipResult();
|
|
this.outputStreamEnhancer = outputStreamEnhancer;
|
|
}
|
|
|
|
private ZipOutputStream createNewZipOutputStream() throws IOException, InvalidAlgorithmParameterException, NoSuchPaddingException,
|
|
NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException {
|
|
|
|
String actualZipFilename = createOutputFilename();
|
|
actualZipFile = destinationDir.resolve(actualZipFilename).toFile();
|
|
|
|
LOG.info("Creating zip part {}: {}", fileCount, actualZipFilename);
|
|
|
|
countingOutputStream = new CountingOutputStream(outputStreamEnhancer.enhance(new BufferedOutputStream(new FileOutputStream(actualZipFile), bufferSize)));
|
|
return new ZipOutputStream(countingOutputStream);
|
|
}
|
|
|
|
private String createOutputFilename() {
|
|
return String.format("%s_%02d.zip", baseName, fileCount);
|
|
}
|
|
|
|
public void write(InputStream inputStream, String path) throws IOException, InvalidAlgorithmParameterException, NoSuchPaddingException,
|
|
NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException {
|
|
|
|
if (countingOutputStream == null) {
|
|
zipOutputStream = createNewZipOutputStream();
|
|
}
|
|
if (bytesWritten >= chunkSize) {
|
|
switchOutputFile();
|
|
}
|
|
LOG.info("Writing file {} to zip", path);
|
|
zipOutputStream.putNextEntry(new ZipEntry(path));
|
|
bytesWritten += IOUtils.copyLarge(inputStream, zipOutputStream);
|
|
zipOutputStream.closeEntry();
|
|
}
|
|
|
|
private void switchOutputFile() throws IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchProviderException {
|
|
LOG.info("Switching zip");
|
|
zipOutputStream.flush();
|
|
zipOutputStream.close();
|
|
addZipToResult();
|
|
fileCount++;
|
|
zipOutputStream = createNewZipOutputStream();
|
|
bytesWritten = 0;
|
|
}
|
|
|
|
public void close() throws IOException {
|
|
LOG.info("Closing zip {}", actualZipFile.getName());
|
|
zipOutputStream.flush();
|
|
zipOutputStream.close();
|
|
addZipToResult();
|
|
}
|
|
|
|
public ZipResult getZipResult() {
|
|
return this.zipResult;
|
|
}
|
|
|
|
private void addZipToResult() throws IOException {
|
|
zipResult.add(actualZipFile.getName(), countingOutputStream.getCount());
|
|
Files.setPosixFilePermissions(actualZipFile.toPath(), ZIP_FILE_PERMISSIONS);
|
|
}
|
|
}
|