使用commons-compress操作zip文件(压缩和解压缩)

本文介绍了一个用于文件压缩和解压缩的实用工具类,使用 Apache Commons Compress 库支持多种格式,如 ZIP 和 TAR。提供了压缩文件到 ZIP 格式及从 ZIP 文件解压缩的示例代码。
  Apache Commons Compress是一个压缩、解压缩文件的类库。

  可以操作ar, cpio, Unix dump, tar, zip, gzip, XZ, Pack200 and bzip2格式的文件,功能比较强大。

  在这里写两个用Commons Compress把文件压缩成zip和从zip解压缩的方法。

  直接贴上工具类代码:






package rockecsn.jaker;



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.io.OutputStream;



import org.apache.commons.compress.archivers.ArchiveEntry;

import org.apache.commons.compress.archivers.zip.Zip64Mode;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;

import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;

import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;





/**

* Zip文件工具类

* @author jaker

*/

public class ZipFileUtil {



/**

* 把文件压缩成zip格式

* @param files 需要压缩的文件

* @param zipFilePath 压缩后的zip文件路径 ,如"D:/test/aa.zip";

*/

public static void compressFiles2Zip(File[] files,String zipFilePath) {

if(files != null && files.length >0) {

if(isEndsWithZip(zipFilePath)) {

ZipArchiveOutputStream zaos = null;

try {

File zipFile = new File(zipFilePath);

zaos = new ZipArchiveOutputStream(zipFile);

//Use Zip64 extensions for all entries where they are required

zaos.setUseZip64(Zip64Mode.AsNeeded);



//将每个文件用ZipArchiveEntry封装

//再用ZipArchiveOutputStream写到压缩文件中

for(File file : files) {

if(file != null) {

ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(file,file.getName());

zaos.putArchiveEntry(zipArchiveEntry);

InputStream is = null;

try {

is = new BufferedInputStream(new FileInputStream(file));

byte[] buffer = new byte[1024 * 5];

int len = -1;

while((len = is.read(buffer)) != -1) {

//把缓冲区的字节写入到ZipArchiveEntry

zaos.write(buffer, 0, len);

}

//Writes all necessary data for this entry.

zaos.closeArchiveEntry();

}catch(Exception e) {

throw new RuntimeException(e);

}finally {

if(is != null)

is.close();

}



}

}

zaos.finish();

}catch(Exception e){

throw new RuntimeException(e);

}finally {

try {

if(zaos != null) {

zaos.close();

}

} catch (IOException e) {

throw new RuntimeException(e);

}

}



}



}



}



/**

* 把zip文件解压到指定的文件夹

* @param zipFilePath zip文件路径, 如 "D:/test/aa.zip"

* @param saveFileDir 解压后的文件存放路径, 如"D:/test/"

*/

public static void decompressZip(String zipFilePath,String saveFileDir) {

if(isEndsWithZip(zipFilePath)) {

File file = new File(zipFilePath);

if(file.exists()) {

InputStream is = null;

//can read Zip archives

ZipArchiveInputStream zais = null;

try {

is = new FileInputStream(file);

zais = new ZipArchiveInputStream(is);

ArchiveEntry archiveEntry = null;

//把zip包中的每个文件读取出来

//然后把文件写到指定的文件夹

while((archiveEntry = zais.getNextEntry()) != null) {

//获取文件名

String entryFileName = archiveEntry.getName();

//构造解压出来的文件存放路径

String entryFilePath = saveFileDir + entryFileName;

byte[] content = new byte[(int) archiveEntry.getSize()];

zais.read(content);

OutputStream os = null;

try {

//把解压出来的文件写到指定路径

File entryFile = new File(entryFilePath);

os = new BufferedOutputStream(new FileOutputStream(entryFile));

os.write(content);

}catch(IOException e) {

throw new IOException(e);

}finally {

if(os != null) {

os.flush();

os.close();

}

}



}

}catch(Exception e) {

throw new RuntimeException(e);

}finally {

try {

if(zais != null) {

zais.close();

}

if(is != null) {

is.close();

}

} catch (IOException e) {

throw new RuntimeException(e);

}

}

}

}

}



/**

* 判断文件名是否以.zip为后缀

* @param fileName 需要判断的文件名

* @return 是zip文件返回true,否则返回false

*/

public static boolean isEndsWithZip(String fileName) {

boolean flag = false;

if(fileName != null && !"".equals(fileName.trim())) {

if(fileName.endsWith(".ZIP")||fileName.endsWith(".zip")){

flag = true;

}

}

return flag;

}



}


  再来测试一下:


package rockecsn.jaker;



import java.io.File;



import org.junit.Test;



import cn.luxh.utils.ZipFileUtil;



/**

* 测试ZipFileUtil的压缩和解压缩方法

* @author jaker

*/

public class ZipFileUtilTest {



@Test

public void testCompressFiles2Zip() {

//存放待压缩文件的目录

File srcFile = new File("D:/test");

//压缩后的zip文件路径

String zipFilePath = "d:/test2/test.zip";

if(srcFile.exists()) {

File[] files = srcFile.listFiles();

ZipFileUtil.compressFiles2Zip(files, zipFilePath);

}

}



@Test

public void testDecompressZip() {

//压缩包所在路径

String zipFilePath = "d:/test2/test.zip";

//解压后的文件存放目录

String saveFileDir = "d:/test2/";

//调用解压方法

ZipFileUtil.decompressZip(zipFilePath, saveFileDir);

}

}
commons-compress是一个开源的Java库,它提供了压缩和解压缩各种不同格式的文件的功能。 在使用commons-compress来实现zip文件分卷压缩时,需要使用ZipArchiveOutputStream类和SplitOutputStream类。 ZipArchiveOutputStream类是用于创建zip文件的类,SplitOutputStream类是用于将输出流分成多个部分的类。 下面是一个示例代码,实现将一个较大的zip文件分成多个大小相等的文件: ```java import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream; import org.apache.commons.compress.utils.SplitOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class ZipSplitter { private static final int BUFFER_SIZE = 4096; private static final int SPLIT_SIZE = 1024 * 1024 * 100; // 100MB public static void main(String[] args) throws IOException { String sourceFilePath = "source.zip"; String splitFilePath = "source.zip.part"; int partCount = 0; FileInputStream inputStream = new FileInputStream(sourceFilePath); SplitOutputStream outputStream = new SplitOutputStream(new FileOutputStream(splitFilePath), SPLIT_SIZE); ZipArchiveOutputStream zipOutputStream = new ZipArchiveOutputStream(outputStream); byte[] buffer = new byte[BUFFER_SIZE]; int read = 0; ZipArchiveEntry entry; while ((entry = zipInputStream.getNextZipEntry()) != null) { zipOutputStream.putArchiveEntry(entry); while ((read = inputStream.read(buffer)) > 0) { zipOutputStream.write(buffer, 0, read); } zipOutputStream.closeArchiveEntry(); } zipOutputStream.finish(); zipOutputStream.close(); } } ``` 在上述代码中,我们首先定义了一个BUFFER_SIZE常量和一个SPLIT_SIZE常量。BUFFER_SIZE是用于读取文件的缓冲区大小,SPLIT_SIZE是每个分卷文件的大小。 接着,我们使用FileInputStream类打开源zip文件的输入流,使用SplitOutputStream类创建输出流,将分卷文件的输出流传入构造函数,并指定每个分卷文件的大小。 然后,我们使用ZipArchiveOutputStream类创建一个新的zip文件,将ZipArchiveEntry对象和源zip文件中的内容写入新的zip文件中。 最后,我们调用finish()方法和close()方法,将输出流关闭。 需要注意的是,我们生成的分卷文件名是source.zip.part,这是为了在解压缩时能够方便地识别文件。如果生成的分卷文件名与源文件名相同,可能会导致解压缩时出现问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值