时间很少,我稍微简单点儿写。。。
用法不单独写了,直接给代码加注释
压缩和解压缩全都是“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("全部完成。");
}
}