您的位置:首页 > 编程语言 > Java开发

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

2017-03-31 20:39 696 查看
在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(); }}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java api 压缩 zip