Java: 压缩流的简单应用(快速入门)

时间很少,我稍微简单点儿写。。。

用法不单独写了,直接给代码加注释

压缩和解压缩全都是“try-循环-try-循环”结构的代码,但这不是一定的,比如你想使用finally关闭资源,就无需带资源的try块;或者用throws字句标记异常处理,就无需try块;或者你想将内容一次性写入文件,内层循环就不必了。

代码如下:

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

/**
 * To unzip a compressed file or compress files into one.
 *
 * @author Hippo
 *
 */
public class Zipper
{
    public static void main(String[] args)
    {
        unzip();
//        zip();
    }
    
    /**
     * 解压缩
     * 假设bag.zip中有三个文件:1.txt,2.txt,3.txt,它们全都不是文件夹
     */
    public static void unzip()
    {
        // 源文件,一个压缩包,类型为File(普通文件)
        File file = new File("C:\\Users\\Administrator\\Desktop\\bag.zip");
        // 将压缩包的内容解压到同名的文件夹中
        new File("C:\\Users\\Administrator\\Desktop\\bag").mkdirs();
        
        // try块放入两个参数:
        // (1) ZipInputStream,压缩输入流,将压缩包从流读入
        // (2) ZipFile,表明源文件是一个压缩文件。和流一样,该资源需要被关闭
        try (ZipInputStream zis = new ZipInputStream(new FileInputStream(file));
                ZipFile zippedFile = new ZipFile(file))
        {
            // ZipEntry是指压缩包中的文件(压缩条目)。1.txt,2.txt,3.txt都分别是一个ZipEntry
            ZipEntry zen = null;
            // 遍历所有条目
            while ((zen = zis.getNextEntry()) != null)
            {
                // 将当前条目解压到以下路径,并创建该空文件
                File newFile = new File("C:\\Users\\Administrator\\Desktop\\bag\\" + zen.getName());
                newFile.createNewFile();
                // ZipFile对象有getInputStream方法用于获取某条目的输入流
                // 也就是说,读入压缩文件需要输入流,压缩文件中的每个条目也都需要各自的输入流
                // BufferedOutputStream就是为了写文件而存在
                try (InputStream in = zippedFile.getInputStream(zen);
                        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(newFile)))
                {
                    int length = 0;  // 当次实际长度
                    byte[] bytes = new byte[1024 * 16];
                    while ((length = in.read(bytes, 0, 1024)) != -1)
                        bos.write(bytes, 0, length);
                }
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    
    /**
     * 压缩
     * 将test.txt,test2.txt",test6.txt,test61.txt,test62.txt文件打成一个压缩包
     */
    public static void zip()
    {
        // 待压缩的文件数组
        File[] files = {
            new File("C:\\Users\\Administrator\\Desktop\\test.txt"),
            new File("C:\\Users\\Administrator\\Desktop\\test2.txt"),
            new File("C:\\Users\\Administrator\\Desktop\\test6.txt"),
            new File("C:\\Users\\Administrator\\Desktop\\test61.txt"),
            new File("C:\\Users\\Administrator\\Desktop\\test62.txt")
        };
        // 即将形成的压缩文件的路径
        File zippedFile = new File("C:\\Users\\Administrator\\Desktop\\TESTS.ZIP");
        // 以下两个变量用于计算压缩进度(已完成的文件数除以总文件数)
        // 其实用字节数计算进度更科学
        int i = 0;
        int total = files.length;
        
        // ZipOutputStream,即压缩输出流,将待压缩的文件通过该流写到压缩包里
        try (ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zippedFile))))
        {
            // 遍历所有待压缩的文件
            for (File each : files)
            {
                // BufferedInputStream用于获得待压缩文件的输入流
                try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(each)))
                {
                    // putNextEntry用于将文件放到压缩包里,每个文件都是一个条目(ZipEntry对象)
                    zos.putNextEntry(new ZipEntry(each.getName()));
                    int length = 0;
                    byte[] bytes = new byte[1024 * 16];
                    while ((length = bis.read(bytes, 0, 1024)) != -1)
                        zos.write(bytes, 0, length);
                }
                // 打印进度
                if (++i != total)
                {
                    String progress = String.format("%.2f%%……", i * 100. / total);
                    System.out.println("已完成:" + progress);
                }
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        System.out.println("全部完成。");
    }
}

在进阶的路上,欢迎各位大神指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值