今天和大家分享三种 JAVA 原生的压缩文件方法。
1. GZIP
将输出流封装成 GZIPOutputStream,将输入流封装成 FileInputStream ,剩下的就是基本的 I/O 读写。
public class GZIPCompress {
public static void main(String[] args) throws IOException {
BufferedOutputStream out =
new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream("abc.gz")));
System.out.println("Writing file");
out.write("ABCDEFG".getBytes());
out.close();
System.out.println("Reading file");
BufferedReader reader =
new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream("abc.gz"))));
while (reader.ready()) {
System.out.print((char) reader.read());
}
reader.close();
}
}
Writing file
Reading file
ABCDEFG
2. ZIP
原生的类库支持将多个文件打包成 ZIP 。
CheckedOutputStream 和 CheckedInputStream 可以用来计算文件的校验和,保证文件的完整性;提供两种方式进行计算,分别是 Adler32(快一些) 和 CRC32(慢一些,更准确) 。
ZipEntry 对应每个被压缩的文件,提供获取文件名、大小、日期、CRC 校验、注释等方法,虽然 CheckedOutputStream 和 CheckedInputStream 支持 Adler32 和 CRC32 两种类型的校验和,但 ZipEntry 只提供支持 CRC 的接口。
ZipInputStream 提供 getNextEntry() 判断是否存在后续元素来进行遍历;不过还有一个更简便的方法就是利用 ZipFile 中 entries() 返回的 Enumeration 进行遍历。
public class ZipCompress {
public static void main(String[] args) throws IOException {
FileOutputStream f = new FileOutputStream("test.zip");
CheckedOutputStream cos = new CheckedOutputStream(f, new Adler32());
ZipOutputStream zos = new ZipOutputStream(cos);
BufferedOutputStream out = new BufferedOutputStream(zos);
//设置压缩包的注释
zos.setComment("A test of Java Zipping");
//压缩文件
String[] files = {"a.txt", "b.txt", "c.txt"};
for (String file : files) {
System.out.println("Writing file " + file);
BufferedReader in = new BufferedReader(new FileReader(file));
zos.putNextEntry(new ZipEntry(file));
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
in.close();
out.flush();
}
out.close();
//检查校验和
System.out.println("Checksum " + cos.getChecksum().getValue());
//解压文件
System.out.println("Reading File");
FileInputStream fi = new FileInputStream("test.zip");
CheckedInputStream cis = new CheckedInputStream(fi, new Adler32());
ZipInputStream in2 = new ZipInputStream(cis);
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.print((char) x+" ");
}
System.out.println();
}
//检查校验和
System.out.println("Checksum: " + cis.getChecksum().getValue());
bis.close();
//第二种解压方式
ZipFile zf = new ZipFile("test.zip");
Enumeration<? extends ZipEntry> e = zf.entries();
while (e.hasMoreElements()) {
ZipEntry zipEntry = e.nextElement();
System.out.println("File " + zipEntry);
}
}
}
Writing file a.txt
Writing file b.txt
Writing file c.txt
Checksum 2597206448
Reading File
Reading file a.txt
A A A
Reading file b.txt
B B B
Reading file c.txt
C C C
Checksum: 2597206448
File a.txt
File b.txt
File c.txt
3. JAR
最后,我们也可以利用 JDK 自带的 jar 程序进行压缩文件,可以用命令行的方式进行调用,如下所示:
jar [options] destination [manifest] inputfile(s)
destination 为目标文件, manifest 为文件清单, inputfile 代表多个打包文件。
options 的具体参数如下:
参数 | 作用 |
---|---|
c | 创建一个新的或空的压缩文档 |
t | 列出目录表 |
x | 解压所有文件 |
x file | 解压该文件 |
f | 指定输出文件名 |
m | 表示指定文件清单 manifest |
v | 产生详细输出 |
O | 只存储文件,不压缩文件 |
M | 不自动创建文件清单 |
- 单个文件压缩
jar cvf test.jar test
已添加清单
正在添加: test/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: test/a.txt(输入 = 12) (输出 = 14)(压缩了 -16%)
正在添加: test/b.txt(输入 = 20) (输出 = 19)(压缩了 5%)
正在添加: test/bigFile.txt(输入 = 150994943) (输出 = 146785)(压缩了 99%)
正在添加: test/test.txt(输入 = 0) (输出 = 0)(存储了 0%)
- 多个文件压缩
jar cvf app.jar audio img
已添加清单
正在添加: audio/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: audio/audio.txt(输入 = 5) (输出 = 7)(压缩了 -40%)
正在添加: img/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: img/img.txt(输入 = 3) (输出 = 5)(压缩了 -66%)
- 文件解压
jar xvf test.jar
已创建: META-INF/
已解压: META-INF/MANIFEST.MF
已创建: test/
已解压: test/a.txt
已解压: test/b.txt
已解压: test/bigFile.txt
已提取: test/test.txt
本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。
若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!