Java I/O库中的类支持读写压缩格式的数据流,你可以用他们对其他的I/O类进行封装,提供压缩功能.
这些类继承自inputStream和OutputStream.因为压缩类库是按字节方式而非字符方式处理,如果被迫要混合使用两种类型数据流可以使用InputStreamReader和OutputStreamWriter在两种类型中方便的转换.
压缩类 | 功能 |
---|---|
CheckInputStream | 为任何InputStream提供校验和(不仅是解压缩) |
CheckOutputStream | 为任何OutputStream提供校验和(不仅是压缩) |
DeflaterOutputStream | 压缩类的基类 |
ZipOutputStream | 用于将数据压缩成Zip格式 |
GZipOutputStream | 用于将数据压缩成GZip格式 |
InflaterInputStream | 解压缩类的基类 |
ZipInputStream | 用于解压缩zip文件格式的数据 |
GZipInputStream | 用于解压缩GZip文件格式的数据 |
- ZipEntry 类:表示 ZIP 文件条目
- ZipFile 类:此类用于从 ZIP 文件读取条目
尽管存在很多压缩算法,但zip和gzip可能是最常用的,因此可以很容易的使用这些工具操作我们的压缩数据.
用GZIP进行简单压缩
public static void main(String[] args) throws IOException {
if (args.length == 0) {
System.out.println("no filePath!");
args = new String[1];
args[0]="out\data.txt";
//System.exit(1);
}
BufferedReader in = new BufferedReader(new FileReader(args[0]));
BufferedOutputStream out = new BufferedOutputStream(
new GZIPOutputStream(
new FileOutputStream("out\test.gzip")));
System.out.println("writing file");
int c;
while((c = in.read())!=-1)
out.write(c);
in.close();
out.close();
System.out.println("reading file");
in = new BufferedReader(
new InputStreamReader(new GZIPInputStream(new FileInputStream("out\test.gzip")))
);
String s;
while((s =in.readLine())!=null){
System.out.println(s);
}
}
用zip进行多个文件保存
支持zip格式的Java库更加全面,可以方便的保存多个文件,还有独立的用于读取zip文件的类.下面的例子显示了用checksum类计算和校验文件的校验和的方法.
有两个checksum类型
- Adler32更快一些
- CRC32慢一些 跟准去
public static void main(String[] args) throws IOException {
args = new String[2];
args[0]="out\data.txt";
args[1]="out\out.dat";
FileOutputStream of = new FileOutputStream("out\test.zip");
CheckedOutputStream csum = new CheckedOutputStream(of,new Adler32());
ZipOutputStream zipOutputStream = new ZipOutputStream(csum);
BufferedOutputStream out = new BufferedOutputStream(zipOutputStream);
zipOutputStream.setComment("test of Java Zipping");
for(String s:args){
System.out.println("writing file "+s);
BufferedReader in = new BufferedReader(new FileReader(s));
zipOutputStream.putNextEntry(new ZipEntry(s));
int c;
while((c = in.read())!=-1){
out.write(c);
}
in.close();
out.flush();
}
out.close();
System.out.println("checksum : "+csum.getChecksum().getValue());
System.out.println("reading file ");
FileInputStream fi = new FileInputStream("out\test.zip");
CheckedInputStream csumi = new CheckedInputStream(fi,new Adler32());
ZipInputStream in2 = new ZipInputStream(csumi);
BufferedInputStream bis = new BufferedInputStream(in2);
ZipEntry ze;
while((ze = in2.getNextEntry())!=null){
System.out.println("reading file"+ze);
int x;
while((x=bis.read())!=-1){
System.out.write(x);
}
System.out.println();
}
if(args.length == 1)
System.out.println("checksum :"+csumi.getChecksum().getValue());
bis.close();
ZipFile zipFile = new ZipFile("out\test.zip");
Enumeration e = zipFile.entries();
while(e.hasMoreElements()){
ZipEntry ze2 = (ZipEntry)e.nextElement();
System.out.println("file:"+ze2);
}
}
加入压缩档案的文件都必须调用putNextEntry()方法,并给其传递一个zipEntry对象.zipEntry是一个功能广泛的接口,可以获取和设置压缩包内该特定项上所有可以利用的数据:名字,压缩和未压缩大小,日期,crc校验和,额外字段数据,注释等等.但是Java的zip库并不支持设置密码,而且zipEntry底层只有一个crc的接口,因此不能使用速度更快的adler32.
getNextEntry()
:解压缩时使用,返回下一个ZipEntry.
解压缩的简便方法为使用ZipFile对象,使用zipFile.entries()方法获得一个ZipEntry的枚举.
zip流可以使用setComment()添加注释,但是无法获取,只能通过zipEntry才能以逐条方式支持注释的获取.