[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较好。

发布了57 篇原创文章 · 获赞 55 · 访问量 1928

猜你喜欢

转载自blog.csdn.net/qq_40561126/article/details/104974459