[Java]還在用360壓縮嗎?自己寫一個吧

Java中的I/O支持讀寫壓縮格式的數據流,我們可以對其進行封裝以達到壓縮和解壓縮的目的。
這些類並不是從Reader、Writer繼承來的,而是屬於InputStream、OutputStream繼承體系的一部分。也就是說他們面向的是對字節的操作。如果我們必須面向字符進行操作,可以使用InputStreamReader、OutputStreamWriter進行很方便的轉換。

壓縮類 功能
CheckedInputStream GetCheckSum()爲任何inputStream產生校驗和
CheckOutputStream GetCheckSum()爲任何Outputstream產生校驗和
DeflaterOutputStream 壓縮類的基類
ZipOutputStream DeflaterOutputStream的實現類,可以將數據流壓縮爲Zip格式的文件
GZIPOutputStream DeflaterOutputStream的實現類,可以將數據流壓縮爲GZIP格式的文件
InflaterInputStream 解壓縮類的基類
ZipInputStream InfalterInputStream的實現類,可以對Zip格式的文件進行解壓縮
GZIPInputStream InfalterInputStream的實現類,可以對Zip格式的文件進行解壓縮

GZIP格式的壓縮與解壓縮
GZIP比較簡單,適合對單個文件進行壓縮和解壓縮。

package com.mfs.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GZIPCompress {

	/*
	 * 壓縮
	 * 參數: file指定要壓縮的文件,path指定壓縮後的文件的存儲路徑
	 * 返回值:返回壓縮後的文件的絕對路徑
	 */
	public String compress(String file,String path) throws IOException {
		BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(file)));     
		BufferedOutputStream out = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream(new File(path + "/GZIPCompress.gz"))));
		byte[] b = new byte[1024];
		int n = 0;
		while ((n = in.read(b)) != -1) {
			out.write(b, 0, n);
		}
		in.close();
		out.close();
		return new File(path + "/GZIPcompress.gz").getAbsolutePath();   
	}
	/*
	 * 解壓縮
	 * 參數: 要解壓縮的目標文件
	 */
	public void deCompress (String file) throws FileNotFoundException, IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(new File(file))))); //使用InputStream把面向字節流的對象轉換成面向字符流的對象
		String s;
		while ((s = in.readLine()) != null) {
			System.out.println(s);
		}
		in.close();
	}
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		GZIPCompress gz = new GZIPCompress();
		String GZIPFile = gz.compress("src/com/mfs/io/GZIPCompress.java", "resource");   //將當前文件壓縮壓縮到本項目的resource文件夾下
		gz.deCompress(GZIPFile);  //解壓縮壓縮後的文件
	}

}

Zip文件的壓縮和解壓縮
Zip有一個獨立的類,所以包含的功能非常全面,它可以支持多個文件的壓縮,壓縮後的文件遵循標準的zip標準,所以很容易與市面上的壓縮軟件協同合作。

package com.mfs.io;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.zip.Adler32;
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;

public class ZipCompress {

	/*
	 * 壓縮
	 * 參數: file指定要壓縮的文件,path指定壓縮後的文件的存儲路徑
	 * 返回值:返回壓縮後的文件的絕對路徑
	 */
	public String compress (String[] file,String path) throws IOException {
		ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(new File(path + "/ZipCompress.zip")));
		CheckedOutputStream csum = new CheckedOutputStream(zos, new Adler32()); //用於產生校驗和,可以爲任何InputStream產生校驗和,有兩種方法Adler32(快)、CRC32(慢,準確)
		BufferedOutputStream out = new BufferedOutputStream(csum);
		for (String f : file) {
			BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File(f)));
			zos.putNextEntry(new ZipEntry(f));   //每次向壓縮文件夾中加入新的文件必掉用putNextEntry()方法,參數爲ZipEntry對象
			int n = 0;
			while ((n = in.read()) != -1) {
				out.write(n);
			}
			in.close();
		}
		out.close();
		//System.out.println(csum.getChecksum().getValue()); //校驗和
		return new File(path + "/ZipCompress.zip").getAbsolutePath();
	}
	/*
	 * 解壓縮
	 * 參數: 要解壓縮的目標文件
	 */
	public void deCompress (String file) throws IOException {
		ZipInputStream zis = new ZipInputStream(new FileInputStream(new File(file)));
		CheckedInputStream csum = new CheckedInputStream(zis, new Adler32());   //校驗和
		BufferedReader in = new BufferedReader(new InputStreamReader(csum));
		ZipEntry ze;
		while ((ze = zis.getNextEntry()) != null) {  
			String s;
			while ((s = in.readLine()) != null) {
				System.out.println(s);
			}
		}
		//System.out.println(csum.getChecksum().getValue());
		in.close();
	}
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		String[] file = new String[] {"src/com/mfs/io/ZipCompress.java","src/com/mfs/io/GZIPCompress.java"};
		ZipCompress zip = new ZipCompress();
		String zipFile = zip.compress(file, "resource");
		zip.deCompress(zipFile);
	}

}

對於每一個要加入壓縮文件的文件,都必須調用putNextEntry(),並向其傳遞一個ZipEntry對象。ZipEntry對象包含了一個功能非常全面的接口,受用該對象,我們可以很方便的設置和使用壓縮文件中對應文件的相關信息,如:名字、壓縮的和未壓縮的文件大小、日期、crc校驗和(ZipEntry不支持Adler32)。
解壓縮文件還有一個更簡單的方法,那就是使用ZipFile類:

public void deCompress2 (String file) throws ZipException, IOException {
		ZipFile zip = new ZipFile(new File(file));
		Enumeration<? extends ZipEntry> entries = zip.entries();
		while (entries.hasMoreElements()) {
			ZipEntry ze = entries.nextElement();
			BufferedReader in = new BufferedReader(new InputStreamReader(zip.getInputStream(ze)));
			String s;
			while ((s = in.readLine()) != null) {
				System.out.println(s);
			}
			in.close();
		}
	}

Zip流中的setComment()方法可以增加一些註釋,但是令人疑惑的是卻沒有任何獲取註釋的方法,如果我們想獲取註釋的話還是把註釋放到ZipEntry較好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章