Java文件压缩与解压之java.util.zip的使用

在Java程序可以使用ZIP API 能中来进行文件压缩。本文将介绍Java ZIP API是如何使用。

ZipFile类

Java ZipFile类可以用来读取ZIP文件。为了使用ZipFile类,首先必须创建ZipFile实例。

ZipFile zipFile = new ZipFile("d:\\data\\myzipfile.zip");

构造函数接受一个参数,这个参数是ZIP要打开的文件路径。

ZipEntry类

为了读取ZIP中的每个文件项需要创建ZipEntry(描述Zip文件项),通过调用ZipFile类的getEntry()方法来获取ZipEntry对象。

ZipEntry zipEntry = zipFile.getEntry("file1.txt");

上述代码通过ZipEntry来表示在Zip压缩包中的文件。如果所要提取的文件在ZIP文件中的不同目录下,则需要包含指定的路径名。

ZipEntry zipEntry = zipFile.getEntry("dir/subdir/file1.txt");

当获得ZipEntry可以通过ZipEntry来读取文件。为了读取ZipEntry所表示的文件,需要通过ZipFile获取输入流。

ZipEntry zipEntry = zipFile.getEntry("dir/subdir/file1.txt");
InputStream inputStream = this.zipFile.getInputStream(zipEntry);

通过ZipFile类getInputStream()获取的输入流可以像Java中其它的输入流一样来进行读取。

ZipFile与ZipEntry使用示例

使用ZipFile与ZipEntry读取文件演示代码

压缩文件中onLineBill.zip有一个文件onLineBill.txt,下列代码读取压缩文件中的文件并输出前1000字节。

public class Main2 {
    public static void main(String[] args) throws IOException {
        byte[] buf = new byte[1000];
        ZipFile zipFile = new ZipFile("D:\\onLineBill.zip");
        ZipEntry zipEntry = zipFile.getEntry("onLineBill.txt");
        InputStream inputStream = zipFile.getInputStream(zipEntry);
        inputStream.read(buf);
        System.out.println(new String(buf));
    }
}

列出所有ZipFile中的文件项

使用ZipFile的entries()方法来获取所有ZipFile中的文件。

Enumeration<? extends ZipEntry> entries = zipFile.entries();

通过entries()返回的Enumeration方法来遍历所有文件。本例中现有压缩文件 Archive.zip内部包含两个文本文件。onLineBill.txt、onLineBill2.txt代码读取zip文件并打印各个文件名。最终输出onLineBill.txt、onLineBill2.txt

public class Main2 {
    public static void main(String[] args) throws IOException {
        byte[] buf = new byte[1000];
        ZipFile zipFile = new ZipFile("D:\\Archive.zip");
        Enumeration<? extends ZipEntry> entries = zipFile.entries();
        while(entries.hasMoreElements()){
            ZipEntry entry = entries.nextElement();
            System.out.println(entry.getName());
        }
    }
}

向zip压缩包中写入多个文本文件

public class Zip {
    public static void main(String[] args) throws IOException {

        File file = new File("D:\\f.zip");
        FileOutputStream fos = new FileOutputStream(file);

        ZipOutputStream zip = new ZipOutputStream(fos);

        ZipEntry entry = new ZipEntry("test.txt");
        zip.putNextEntry(entry);        
        zip.write("a simple txt".getBytes());

        ZipEntry entry2 = new ZipEntry("test2.txt");
        zip.putNextEntry(entry2);
        zip.write("a simple file2".getBytes());

        zip.closeEntry();
        zip.close();
    }
}
  • 首先使用FileOutputStream
    对象作为参数创建ZipOutputStream对象。即指定了压缩文件最终的位置。当然也可以将输出目标定向为其它位置,如socket流中。
  • 创建ZipEntry,ZipEntry表示Zip包中一个文件项。接着将ZipEntry对象添加至ZipOutputStream中,随后的写入操作会将数据写入到ZipEntry定义的文件项中。
  • 写入字符串。
  • 关闭ZipEntry,将写入位置定位到该ZipEntry的结尾。
  • 关闭Zip与文件输出流。

这里写图片描述

若要将文件夹中的所有文件进行压缩,遍历文件夹下的文件逐个添加到Zip包中即可。

    File folder = new File(folderPath);
    File files[] = folder.listFiles();

若一个文件夹下既有文件又有文件夹,那么遇到文件直接添加遇到文件夹则递归处理即可。

如果要对应的目录结构,将文件夹加入压缩包,那么在创建ZipEntry时候指定好路径即可。下面的代码将f/t.txt 放入压缩包,其中t.txt在文件夹f下。

ZipEntry entry = new ZipEntry("f/t.txt");

直接向ZipOutputStream写入数据完成压缩

当是Apache poi生成Excel时会用到Workbook的write方法将数据写入到输出流中,这时若要直接将生成的Excel进行压缩,而不是先生成Excel文件,再读取Excel文件写入到压缩流中。那么可以直接调用write方法并传入ZipOutputStream。

public class ExcelTest {

    public static void writeToSheet(Sheet sheet,int n) {
        Row row = sheet.createRow(n);
        Cell cell = row.createCell(0);
        cell.setCellValue("value");
        cell = row.createCell(1);
        cell.setCellValue("value");
    }

    public static void main(String[] args) throws IOException {
        Workbook wb = new HSSFWorkbook();

        Sheet sheet = wb.createSheet();
        writeToSheet(sheet,0);
        writeToSheet(sheet,1);
        writeToSheet(sheet,2);



        FileOutputStream xlsZip = new FileOutputStream("D:\\xlsZip.zip");
        ZipOutputStream zipos = new ZipOutputStream(xlsZip);
        ZipEntry entry = new ZipEntry("xlsZip.xls");
        zipos.putNextEntry(entry);

        wb.write(zipos);

        zipos.closeEntry();

        zipos.close();
        wb.close();
    }
}

上述代码通过POI生成3行Excel并直接写入ZipOutputStream,最后在D:\xlsZip.zip中的压缩包解压后会看到生成的Excel文件。

GZIPOutputStream类

GZIPOutputStream类可以被用来压缩数据并将数据写出到输出流。

创建GZIPOutputStream

FileOutputStream outputStream     = new FileOutputStream("myfile.zip");
GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream);

代码创建了一个GZIPOutputStream并将压缩的数据写入文件中。将数据写入到一个GZIPOutputStream中。

byte[] data = ... ; // get data from somewhere.
gzipOutputStream.write(data);

当写完数据后调用gzipOutputStream.close()方法来关GZIPOutputStream。

也可以使用Java 1.7中的try-with-resources来执行关闭操作。

try(
    FileOutputStream outputStream     = new FileOutputStream("myfile.zip");
    GZIPOutputStream gzipOutputStream = new GZIPOutputStream(outputStream)
    ) {
        byte[] data = ... ; // get data from somewhere.
        gzipOutputStream.write(data);
}

当try-with-resources块退出后,GZIPOutputStream及FileOutputStream将被关闭。

GZIPInputStream

GZIPInputStream可以用来解压缩通过GZIP压缩算法压缩的文件,例如解压通过GZIPOutputStream 类压缩的文件。

创建GZIPInputStream

InputStream     fileInputStream = new FileInputStream("myfile.zip");
GZIPInputStream gzipInputStream = new GZIPInputStream(fileInputStream);

从GZIPInputStream中读取数据,在创建GZIPInputStream后,可以对数据解压缩,即从GZIPInputStream读取数据即可。

int data = gzipInputStream.read();
while(data != -1){
    //do something with data
    data = gzipInputStream.read();
}

关闭GZIPInputStream
嗲用gzipInputStream.close()或通过try-with-resources来关闭资源。

try(GZIPInputStream gzipInputStream = new GZIPInputStream(new FileInputStream("myfile.zip"))) {
    int data = gzipInputStream.read();
    while(data != -1){
        //do something with data
        data = gzipInputStream.read();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值