Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.cloudhopper.commons.util;
/*
* #%L
* ch-commons-util
* %%
* Copyright (C) 2012 Cloudhopper by Twitter
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
//import SevenZip.LzmaAlone;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Utility methods for compressing and uncompressing a file.
*
* @author joelauer (twitter: @jjlauer or http://twitter.com/jjlauer)
*/
public class CompressionUtil {
private static final Logger logger = LoggerFactory.getLogger(CompressionUtil.class);
/**
* Enumeration of all supported compression algorithms by this utility.
*/
public enum Algorithm {
/** gzip */
GZIP("gzip", "gz", new GzipCompressor()),
/** poorly supported for now */
//LZMA("lzma", "7z", new LzmaCompressor()),
/** zip */
ZIP("zip", "zip", new ZipCompressor());
private final String name;
private final String fileExt;
private final Compressor compressor;
Algorithm(final String name, final String fileExt, final Compressor compressor) {
this.name = name;
this.fileExt = fileExt;
this.compressor = compressor;
}
/**
* Gets the name of this compression algorithm such as "gzip".
* @return The name of this compression algorithm
*/
public String getName() {
return this.name;
}
/**
* Gets the extension associated with this compression algorithm such
* as "gz" for gzip or "zip" for zip.
* @return The compression algorithm file extension
*/
public String getFileExtension() {
return this.fileExt;
}
private Compressor getCompressor() {
return this.compressor;
}
/**
* Finds the matching compression algorithm by performing a case insensitive
* search based on its name such as "gzip".
* @param name The algorithm name such as "gzip" or "zip"
* @return The matching algorithm or null if no algorithm was found
*/
public static Algorithm findByName(final String name) {
for (Algorithm e : Algorithm.values()) {
if (e.name.equalsIgnoreCase(name)) {
return e;
}
}
return null;
}
/**
* Finds the matching compression algorithm by performing a case insensitive
* search based on its file extension such as "gz" for gzip.
* @param name The algorithm file extension such as "gz" or "zip"
* @return The matching algorithm or null if no algorithm was found
*/
public static Algorithm findByFileExtension(final String fileExt) {
for (Algorithm e : Algorithm.values()) {
if (e.fileExt.equalsIgnoreCase(fileExt)) {
return e;
}
}
return null;
}
}
/**
* Checks if the compression algorithm is supported by this utility class.
* For example, "gzip" would return true while "unknown" would
* return false.
* @param algorithm The compression algorithm such as "gzip" or "zip"
* @return True if the algorithm is supported, otherwise false.
*/
public static boolean isAlgorithmSupported(String algorithm) {
return (Algorithm.findByName(algorithm) != null);
}
/**
* Checks if the file extension such as "gz" or "zip" is supported by this
* utility class. A file extension is supported if a compression algorithm
* exists.
* @param fileExt The file extension to check such as "gz" or "zip"
* @return True if the file extension is supported, otherwise false.
*/
public static boolean isFileExtensionSupported(String fileExt) {
return (Algorithm.findByFileExtension(fileExt) != null);
}
/**
* Compresses the source file using a variety of supported compression
* algorithms. This method will create a target file in the same
* directory as the source file and will append a file extension matching
* the compression algorithm used. For example, using "gzip" will mean a
* source file of "app.log" would be compressed to "app.log.gz".
* @param sourceFile The uncompressed file
* @param algorithm The compression algorithm to use
* @param deleteSourceFileAfterCompressed Delete the original source file
* only if the compression was successful.
* @return The compressed file
* @throws FileAlreadyExistsException Thrown if the target file already
* exists and an overwrite is not permitted. This exception is a
* subclass of IOException, so its safe to only catch an IOException
* if no specific action is required for this case.
* @throws IOException Thrown if an error occurs while attempting to
* compress the source file.
*/
public static File compress(File sourceFile, String algorithm, boolean deleteSourceFileAfterCompressed) throws FileAlreadyExistsException, IOException {
return compress(sourceFile, sourceFile.getParentFile(), algorithm, deleteSourceFileAfterCompressed);
}
/**
* Compresses the source file using a variety of supported compression
* algorithms. This method will create a destination file in the destination
* directory and will append a file extension matching the compression
* algorithm used. For example, using "gzip" will mean a source file of
* "app.log" would be compressed to "app.log.gz" and placed in the destination
* directory.
* @param sourceFile The uncompressed file
* @param targetDir The target directory or null if same directory as sourceFile
* @param algorithm The compression algorithm to use
* @param deleteSourceFileAfterCompressed Delete the original source file
* only if the compression was successful.
* @return The compressed file
* @throws FileAlreadyExistsException Thrown if the target file already
* exists and an overwrite is not permitted. This exception is a
* subclass of IOException, so its safe to only catch an IOException
* if no specific action is required for this case.
* @throws IOException Thrown if an error occurs while attempting to
* compress the source file.
*/
public static File compress(File sourceFile, File targetDir, String algorithm, boolean deleteSourceFileAfterCompressed) throws FileAlreadyExistsException, IOException {
// make sure the destination directory is a directory
if (!targetDir.isDirectory()) {
throw new IOException("Cannot compress file since target directory " + targetDir + " neither exists or is a directory");
}
// try to find compression algorithm
Algorithm a = Algorithm.findByName(algorithm);
// was it found?
if (a == null) {
throw new IOException("Compression algorithm '" + algorithm + "' is not supported");
}
// create a target file with the default file extension for this algorithm
File targetFile = new File(targetDir, sourceFile.getName() + "." + a.getFileExtension());
compress(a, sourceFile, targetFile, deleteSourceFileAfterCompressed);
return targetFile;
}
/**
* Uncompresses the source file using a variety of supported compression
* algorithms. This method will create a file in the same directory as
* the source file by stripping the compression algorithm's file extension from
* the source filename. For example, using "gzip" will mean a source file of
* "app.log.gz" would be uncompressed to "app.log".
* @param sourceFile The compressed file
* @param deleteSourceFileAfterUncompressed Delete the original source file
* only if the uncompression was successful.
* @return The uncompressed file
* @throws FileAlreadyExistsException Thrown if the target file already
* exists and an overwrite is not permitted. This exception is a
* subclass of IOException, so its safe to only catch an IOException
* if no specific action is required for this case.
* @throws IOException Thrown if an error occurs while attempting to
* uncompress the source file.
*/
public static File uncompress(File sourceFile, boolean deleteSourceFileAfterUncompressed) throws FileAlreadyExistsException, IOException {
return uncompress(sourceFile, sourceFile.getParentFile(), deleteSourceFileAfterUncompressed);
}
/**
* Uncompresses the source file using a variety of supported compression
* algorithms. This method will create a file in the target
* directory by stripping the compression algorithm's file extension from
* the source filename. For example, using "gzip" will mean a source file of
* "app.log.gz" would be uncompressed to "app.log" and placed in the target
* directory.
* @param sourceFile The compressed file
* @param targetDir The target directory or null to uncompress in same directory as source file
* @param deleteSourceFileAfterUncompressed Delete the original source file
* only if the uncompression was successful.
* @return The uncompressed file
* @throws FileAlreadyExistsException Thrown if the target file already
* exists and an overwrite is not permitted. This exception is a
* subclass of IOException, so its safe to only catch an IOException
* if no specific action is required for this case.
* @throws IOException Thrown if an error occurs while attempting to
* uncompress the source file.
*/
public static File uncompress(File sourceFile, File targetDir, boolean deleteSourceFileAfterUncompressed) throws FileAlreadyExistsException, IOException {
//
// figure out compression algorithm used by its extension
//
String fileExt = FileUtil.parseFileExtension(sourceFile.getName());
// was a file extension parsed
if (fileExt == null) {
throw new IOException("File '" + sourceFile + "' must contain a file extension in order to lookup the compression algorithm");
}
// try to find compression algorithm
Algorithm a = Algorithm.findByFileExtension(fileExt);
// was it not found?
if (a == null) {
throw new IOException("Unrecognized or unsupported compression algorithm for file extension '" + fileExt + "'");
}
// make sure the destination directory is a directory
if (!targetDir.isDirectory()) {
throw new IOException("Cannot uncompress file since target directory " + targetDir + " neither exists or is a directory");
}
//
// create a target file by stripping the file extension from the original file
//
String filename = sourceFile.getName();
filename = filename.substring(0, filename.length()-(fileExt.length()+1));
File targetFile = new File(targetDir, filename);
uncompress(a, sourceFile, targetFile, deleteSourceFileAfterUncompressed);
return targetFile;
}
private static void compress(Algorithm a, File sourceFile, File targetFile, boolean deleteSourceFileAfterCompressed) throws FileAlreadyExistsException, IOException {
// check if the src file exists
if (!sourceFile.canRead()) {
throw new IOException("Source file " + sourceFile + " neither exists or can be read");
}
// make sure the target file does not exist!
if (targetFile.exists()) {
throw new FileAlreadyExistsException("Target file " + targetFile + " already exists - cannot overwrite!");
}
// try to compress the file
a.getCompressor().compress(sourceFile, targetFile);
// delete file after compressing
if (deleteSourceFileAfterCompressed) {
sourceFile.delete();
}
}
private static void uncompress(Algorithm a, File sourceFile, File targetFile, boolean deleteSourceFileAfterUncompressed) throws FileAlreadyExistsException, IOException {
// check if the src file exists
if (!sourceFile.canRead()) {
throw new IOException("Source file " + sourceFile + " neither exists or can be read");
}
// make sure the target file does not exist!
if (targetFile.exists()) {
throw new FileAlreadyExistsException("Target file " + targetFile + " already exists - cannot overwrite!");
}
// try to uncompress the file
a.getCompressor().uncompress(sourceFile, targetFile);
// delete file after uncompressing
if (deleteSourceFileAfterUncompressed) {
sourceFile.delete();
}
}
private static void uncompress(Algorithm a, InputStream srcIn, OutputStream destOut) throws IOException {
// try to uncompress the file
a.getCompressor().uncompress(srcIn, destOut);
}
/**
* Interface all supported compression algorithms must implement.
*/
private static interface Compressor {
public void compress(File srcFile, File destFile) throws IOException;
public void compress(InputStream srcIn, OutputStream destOut) throws IOException;
public void uncompress(File srcFile, File destFile) throws IOException;
public void uncompress(InputStream srcIn, OutputStream destOut) throws IOException;
}
/**
* Compressor using the GZIP compression algorithm.
*/
private static class GzipCompressor implements Compressor {
@Override
public void compress(File srcFile, File destFile) throws IOException {
FileInputStream in = null;
GZIPOutputStream out = null;
try {
// create an input stream from the source file
in = new FileInputStream(srcFile);
// create an output stream that's gzipped
out = new GZIPOutputStream(new FileOutputStream(destFile));
// transfer bytes from the input file to the GZIP output stream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
// close the input stream
in.close();
in = null;
// finish and close the gzip file
out.finish();
out.close();
out = null;
} finally {
// make sure everything is closed
if (in != null) {
try { in.close(); } catch (Exception e) { }
}
if (out != null) {
logger.warn("Output stream for GZIP compressed file was not null -- indicates error with compression occurred");
try { out.close(); } catch (Exception e) { }
}
}
}
@Override
public void compress(InputStream srcIn, OutputStream destOut) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void uncompress(File srcFile, File destFile) throws IOException {
InputStream in = new FileInputStream(srcFile);
OutputStream out = new FileOutputStream(destFile);
uncompress(in, out);
}
@Override
public void uncompress(InputStream srcIn, OutputStream destOut) throws IOException {
GZIPInputStream in = null;
try {
// create an input stream from the source
in = new GZIPInputStream(srcIn);
// transfer bytes from the GZIP input file to the output stream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
destOut.write(buf, 0, len);
}
// close the GZIP input stream
in.close();
in = null;
// close the output file
destOut.close();
destOut = null;
} finally {
// make sure everything is closed
if (in != null) {
try { in.close(); } catch (Exception e) { }
}
if (destOut != null) {
try { destOut.close(); } catch (Exception e) { }
}
}
}
}
/**
* Compressor using the ZIP compression algorithm.
*/
private static class ZipCompressor implements Compressor {
@Override
public void compress(File srcFile, File destFile) throws IOException {
FileInputStream in = null;
ZipOutputStream out = null;
try {
// create an input stream from the source file
in = new FileInputStream(srcFile);
// create an output stream that's gzipped
out = new ZipOutputStream(new FileOutputStream(destFile));
// add a new zip entry to the output stream
out.putNextEntry(new ZipEntry(srcFile.getName()));
// transfer bytes from the input file to the zip output stream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
// close the input stream
in.close();
in = null;
// finish and close the gzip file
out.closeEntry();
out.finish();
out.close();
out = null;
} finally {
// always make sure the input stream is closed!
if (in != null) {
try { in.close(); } catch (Exception e) { }
}
// if the out var is not null, then something went wrong above
// and we did not compress the destination file correctly
if (out != null) {
logger.warn("Output stream for ZIP compressed file was not null -- indicates error with compression occurred");
try { out.close(); } catch (Exception e) { }
}
}
}
@Override
public void compress(InputStream srcIn, OutputStream destOut) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void uncompress(File srcFile, File destFile) throws IOException {
InputStream in = new FileInputStream(srcFile);
OutputStream out = new FileOutputStream(destFile);
uncompress(in, out);
}
// NOTE: only reads the first zip file in the archive
@Override
public void uncompress(InputStream srcIn, OutputStream destOut) throws IOException {
ZipInputStream in = null;
try {
// create an input stream from the source
in = new ZipInputStream(srcIn);
// just get the first entry
ZipEntry ze = in.getNextEntry();
// transfer bytes from the GZIP input file to the output stream
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
destOut.write(buf, 0, len);
}
// see if there are more entries in this zip file
if (in.getNextEntry() != null) {
throw new IOException("Zip file/inputstream contained more than one entry (this method cannot support)");
}
// close the zip inputstream
in.closeEntry();
in.close();
in = null;
// close the output file
destOut.close();
destOut = null;
} finally {
// make sure everything is closed
if (in != null) {
try { in.close(); } catch (Exception e) { }
}
if (destOut != null) {
try { destOut.close(); } catch (Exception e) { }
}
}
}
}
/**
* Compressor using the LZMA/7-zip compression algorithm.
*/
/** removed in 6.0.0
private static class LzmaCompressor implements Compressor {
@Override
public void compress(File srcFile, File destFile) throws IOException {
// FIXME: VERY SIMPLE IMPL -- LIKELY SHOULD TRY TO EMULATE THIS BETTER
// by pulling code from its main
try {
// compress using LZMA
LzmaAlone.main(new String[]{"e", srcFile.getCanonicalPath(), destFile.getCanonicalPath()});
} catch (Exception ex) {
logger.error("", ex);
throw new IOException("LZMA compression failed: " + ex.getMessage());
}
}
@Override
public void uncompress(File srcFile, File destFile) throws IOException {
throw new UnsupportedOperationException("LZMA uncompress not supported yet.");
}
@Override
public void uncompress(InputStream srcIn, OutputStream destOut) throws IOException {
throw new UnsupportedOperationException("LZMA uncompress not supported yet.");
}
@Override
public void compress(InputStream srcIn, OutputStream destOut) throws IOException {
throw new UnsupportedOperationException("Not supported yet.");
}
}
*/
}