JAVA原生的文件压缩方法 --《JAVA编程思想》84

今天和大家分享三种 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

本次分享至此结束,希望本文对你有所帮助,若能点亮下方的点赞按钮,在下感激不尽,谢谢您的【精神支持】。

若有任何疑问,也欢迎与我交流,若存在不足之处,也欢迎各位指正!

Java实现压缩与解压缩ZIP   import java.io.BufferedInputStream;   import java.io.BufferedOutputStream;   import java.io.File;   import java.io.FileInputStream;   import java.io.FileOutputStream;   import java.util.zip.ZipEntry;   import java.util.zip.ZipOutputStream;   public class Zip {   static final int BUFFER = 2048;   public static void main(String argv[]) {   try {   BufferedInputStream origin = null;   FileOutputStream dest = new FileOutputStream("E:\\test\\myfiles.zip");   ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(   dest));   byte data[] = new byte[BUFFER];   File f = new File("e:\\test\\a\\");   File files[] = f.listFiles();   for (int i = 0; i < files.length; i++) {   FileInputStream fi = new FileInputStream(files[i]);   origin = new BufferedInputStream(fi, BUFFER);   ZipEntry entry = new ZipEntry(files[i].getName());   out.putNextEntry(entry);   int count;   while ((count = origin.read(data, 0, BUFFER)) != -1) {   out.write(data, 0, count);   }   origin.close();   }   out.close();   } catch (Exception e) {   e.printStackTrace();   }   }   }   解压缩的   import java.io.BufferedInputStream;   import java.io.BufferedOutputStream;   import java.io.File;   import java.io.FileOutputStream;   import java.util.Enumeration;   import java.util.zip.ZipEntry;   import java.util.zip.ZipFile;   public class UnZip {   static final int BUFFER = 2048;   public static void main(String argv[]) {   try {   String fileName = "E:\\test\\myfiles.zip";   String filePath = "E:\\test\\";   ZipFile zipFile = new ZipFile(fileName);   Enumeration emu = zipFile.entries();   int i=0;   while(emu.hasMoreElements()){   ZipEntry entry = (ZipEntry)emu.nextElement();   //会把目录作为一个file读出一次,所以只建立目录就可以,之下的文件还会被迭代到。   if (entry.isDirectory())   {   new File(filePath + entry.getName()).mkdirs();   continue;   }   BufferedInputStream bis = new BufferedInputStream(zipFile.getInputStream(entry));   File file = new File(filePath + entry.getName());   //加入这个的原因是zipfile读取文件是随机读取的,这就造成可能先读取一个文件   //而这个文件所在的目录还没有出现过,所以要建出目录来。   File parent = file.getParentFile();   if(parent != null && (!parent.exists())){   parent.mkdirs();   }   FileOutputStream fos = new FileOutputStream(file);   BufferedOutputStream bos = new BufferedOutputStream(fos,BUFFER);   int count;   byte data[] = new byte[BUFFER];   while ((count = bis.read(data, 0, BUFFER)) != -1)   {   bos.write(data, 0, count);   }   bos.flush();   bos.close();   bis.close();   }   zipFile.close();   } catch (Exception e) {   e.printStackTrace();   }   }   }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BaymaxCS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值