在最近的項目中,我們不得不做一些我個人從未真正看過的事情。 壓縮。 我們需要拍幾個文件和圖像,將它們壓縮并提供給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壓縮 技術 。
編碼愉快!
拜倫
相關文章 :
- Cajo,用Java完成分布式計算的最簡單方法
- Hibernate映射集合性能問題
- Java Code Geeks Andygene Web原型
- Servlet 3.0異步處理可將服務器吞吐量提高十倍
翻譯自: https://www.javacodegeeks.com/2011/05/java-compression.html