在最近的项目中,我们不得不做一些我个人从未真正看过的事情。
压缩。
我们需要拍几个文件和图像,将它们压缩并提供给FTP使用,是的,总有一天,感觉确实回到了90年代。
除了过去的FTP之行外,它还是一个很好的机会,可以花一点时间在这个问题上。
压缩档案
因此,在通常的IO类BufferedInputStream , FileOutputStream和File上面有:
- ZipInputStream –输入流,用于读取ZIP文件格式的文件。 与ZipFile不同,不缓存Zip条目。
- ZipOutputStream –用于以ZIP文件格式写入文件的输出流。 这有一个默认的内部缓冲区512,可以使用BufferedOutputStream来增加它。
- ZipEntry –表示一个zip文件中的条目。
- ZipFile –用于从zip文件读取条目。 条目被缓存。
- CRC32 –用于计算数据流的CRC-32。
下面的示例显示了如何在有和没有校验和的情况下压缩和解压缩文件夹中的文件:
package javaitzen.blog;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* The Class FileCompressionUtil.
*/
public class FileCompressionUtil {
private static final String PATH_SEP = "\\";
public static final int BUFFER = 2048;
private FileCompressionUtil() {}
/**
* Zip files in path.
*
* @param zipFileName the zip file name
* @param filePath the file path
* @throws IOException Signals that an I/O exception has occurred.
*/
public static void zipFilesInPath(final String zipFileName, final String filePath) throws IOException {
final FileOutputStream dest = new FileOutputStream(zipFileName);
final ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest));
try {
byte[] data = new byte[BUFFER];
final File folder = new File(filePath);
final List< String > files = Arrays.asList(folder.list());
for (String file : files) {
final FileInputStream fi = new FileInputStream(filePath + PATH_SEP + file);
final BufferedInputStream origin = new BufferedInputStream(fi, BUFFER);
out.putNextEntry(new ZipEntry(file));
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
fi.close();
}
} finally {
out.close();
dest.close();
}
}
/**
* Zip with checksum. CRC32
*
* @param zipFileName the zip file name
* @param folderPath the folder path
* @return the checksum
* @throws IOException Signals that an I/O exception has occurred.
*/
public static long zipFilesInPathWithChecksum(final String zipFileName, final String folderPath) throws IOException {
final FileOutputStream dest = new FileOutputStream(zipFileName);
final CheckedOutputStream checkStream = new CheckedOutputStream(dest, new CRC32());
final ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(checkStream));
try {
byte[] data = new byte[BUFFER];
final File folder = new File(folderPath);
final List< String > files = Arrays.asList(folder.list());
for (String file : files) {
final FileInputStream fi = new FileInputStream(folderPath + PATH_SEP + file);
final BufferedInputStream origin = new BufferedInputStream(fi, BUFFER);
out.putNextEntry(new ZipEntry(file));
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
} finally {
out.close();
checkStream.close();
dest.flush();
dest.close();
}
return checkStream.getChecksum().getValue();
}
/**
* Unzip files to path.
*
* @param zipFileName the zip file name
* @param fileExtractPath the file extract path
* @throws IOException Signals that an I/O exception has occurred.
*/
public static void unzipFilesToPath(final String zipFileName, final String fileExtractPath) throws IOException {
final FileInputStream fis = new FileInputStream(zipFileName);
final ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fis));
try {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
int count;
byte[] data = new byte[BUFFER];
final FileOutputStream fos = new FileOutputStream(fileExtractPath + PATH_SEP + entry.getName());
final BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);
while ((count = zis.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
}
} finally {
fis.close();
zis.close();
}
}
/**
* Unzip files to path with checksum. CRC32
*
* @param zipFileName the zip file name
* @param fileExtractPath the file extract path
* @param checksum the checksum
* @return true, if checksum matches;
* @throws IOException Signals that an I/O exception has occurred.
*/
public static boolean unzipFilesToPathWithChecksum(final String zipFileName, final String fileExtractPath, final long checksum) throws IOException {
boolean checksumMatches = false;
final FileInputStream fis = new FileInputStream(zipFileName);
final CheckedInputStream checkStream = new CheckedInputStream(fis, new CRC32());
final ZipInputStream zis = new ZipInputStream(new BufferedInputStream(checkStream));
try {
ZipEntry entry = null;
while ((entry = zis.getNextEntry()) != null) {
int count;
byte[] data = new byte[BUFFER];
final FileOutputStream fos = new FileOutputStream(fileExtractPath + PATH_SEP + entry.getName());
final BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);
while ((count = zis.read(data, 0, BUFFER)) != -1) {
dest.write(data, 0, count);
}
dest.flush();
dest.close();
}
} finally {
zis.close();
fis.close();
checkStream.close();
}
if(checkStream.getChecksum().getValue() == checksum) {
checksumMatches = true;
}
return checksumMatches;
}
}
压缩物件
我们最终没有使用对象压缩,但无论如何我还是看了一下。 我做了一些通用的compress / expand util,不知道它是否有用。 我将输入参数保留为OutputStream和InputStream,因为从理论上讲,它可以与从套接字通信到字符串处理的任何流实现一起使用。
这里使用与压缩相关的类:
- GZIPInputStream –一个输入流过滤器,用于读取GZIP文件格式的压缩数据。
- GZIPOutputStream –输出流过滤器,用于以GZIP文件格式写入压缩数据。
- 默认内部缓冲区为512,如果需要更多,请使用BufferedOutputStream 。
package javaitzen.blog;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
* The Class ObjectCompressionUtil.
*
* @param <T> the generic type of the serializable object to be compressed
*/
public class ObjectCompressionUtil<T extends Serializable> {
/**
* Compress object.
*
* @param objectToCompress the object to compress
* @param outstream the outstream
* @return the compressed object
* @throws IOException Signals that an I/O exception has occurred.
*/
public T compressObject(final T objectToCompress, final OutputStream outstream) throws IOException {
final GZIPOutputStream gz = new GZIPOutputStream(outstream);
final ObjectOutputStream oos = new ObjectOutputStream(gz);
try {
oos.writeObject(objectToCompress);
oos.flush();
return objectToCompress;
}finally {
oos.close();
outstream.close();
}
}
/**
* Expand object.
*
* @param objectToExpand the object to expand
* @param instream the instream
* @return the expanded object
* @throws IOException Signals that an I/O exception has occurred.
* @throws ClassNotFoundException the class not found exception
*/
public T expandObject(final T objectToExpand, final InputStream instream) throws IOException,
ClassNotFoundException {
final GZIPInputStream gs = new GZIPInputStream(instream);
final ObjectInputStream ois = new ObjectInputStream(gs);
try {
@SuppressWarnings("unchecked")
T expandedObject = (T) ois.readObject();
return expandedObject;
} finally {
gs.close();
ois.close();
}
}
}
参考:来自Zen的 JCG合作伙伴 Brian的Java压缩 技术 。
编码愉快!
拜伦
相关文章 :
翻译自: https://www.javacodegeeks.com/2011/05/java-compression.html