//UnZip1和UnZip2两个程序使用了两种方式解压zip文件
// Zip程序用来将文件压缩为zip文件
// 解压缩时
// zip文件本身的文件名可以包含中文,zip文件内的文件的内容也可以包含中文
// 但在zip文件内不能有名称包含中文的文件和目录,否则解压程序会报错
// 这是Java类库的一个漏洞,对zip文件内的文件和目录的名称的解读方式有问题
// 可以通过修改ZipInputStream类解决这个问题
// 压缩时,如果被压缩文件中有名称包含中文的文件或目录
// 则在WinZip或WinRar中查看压缩后的zip文件时,对应文件或目录的名称显示为乱码
// 这是Java类库的一个漏洞,压缩文件时对文件和目录的名称的编码方式作了转换
// 可以通过修改ZipOutputStream类解决这个问题
// 上机运行这三个程序
// 根据这三个程序,编写一个满足下面要求的可以压缩和解压缩zip文件的程序
// 程序启动后
// (1)选择是压缩还是解压缩zip文件,或是退出程序
// (2)如果选择压缩
// 输入要压缩的文件或目录,可以输入多个,文件要包含扩展名
// 输入压缩文件名,不包含扩展名
// 显示压缩过程并将压缩过程记入日志文件
// 压缩完毕转向(1)
// (3)如果选择解压缩
// 输入要解压缩的文件,只能输入一个,不包含扩展名
// 输入放置解压后文件的目录
// 选择解压缩方式:UnZip1或UnZip2
// 显示解压缩过程并将解压缩过程记入日志文件
// 解压缩完毕转向(1)
// (4)如果选择退出程序,直接退出程序
// 日志文件格式要求
// (1)日志文件使用文本文件,以"log"为扩展名
// (2)日志记录内容包括
// 程序启动和退出
// 执行的操作(压缩、解压缩)和操作过程
// 错误和异常说明
// (3)程序启动和退出记录以日期时间开头
// 执行操作(压缩、解压缩)记录以日期时间开头
// (4)每条日志记录以换行为分隔符
// 每次程序运行的记录以"一个空行+一行"*"+一个空行"为分隔符
// 每次操作(压缩、解压缩)的记录以一个空行为分隔符
import java.io.*;
import java.util.zip.*;
import java.util.Enumeration;
class UnZip1 {
public void unZip(String filePath, String dirPath)
// filePath是需要解压的zip文件的路径,可以是绝对或相对路径,包含文件的扩展名
// dirPath是用来放置解压后文件的目录的路径,可以是绝对或相对路径
{
File f = new File(filePath);
File dir = new File(dirPath);
filePath = f.getAbsolutePath();
System.out.println("将" + filePath + "解压到" + dir.getAbsolutePath());
if (!f.isFile())
System.out.println(filePath + "文件不存在");
else {
String zipFileName = f.getName();
System.out.println(zipFileName + "开始解压");
if (!dir.isDirectory())
dir.mkdirs(); // 创建放置解压后文件的目录
try {
ZipInputStream in = new ZipInputStream(new FileInputStream(f));
FileOutputStream out;
byte buf[] = new byte[1024]; // 解压缓冲区
ZipEntry zipEntry; // 获取压缩文件中的文件或目录
String zipEntryName;
File file, parent;
int len;
while ((zipEntry = in.getNextEntry()) != null) {
zipEntryName = zipEntry.getName();
System.out
.println(zipFileName + "/" + zipEntryName + "被解压");
if (zipEntry.isDirectory()) // 如果读出的是目录
new File(dir, zipEntryName).mkdirs();
else {
file = new File(dir, zipEntryName);
// 如果读出的这个文件所在目录尚未创建
parent = file.getParentFile();
if (!parent.exists())
parent.mkdirs();
// 如果该文件已存在,直接覆盖
// 如果该文件不存在,自动创建
out = new FileOutputStream(file);
while ((len = in.read(buf, 0, 1024)) != -1)
out.write(buf, 0, len);
out.close();
}
}
in.close();
System.out.println(zipFileName + "解压完毕");
} catch (Exception e) {
System.out.println(e);
System.out.println(zipFileName + "解压失败");
}
}
}
public static void main(String args[]) {
new UnZip1().unZip(args[0], args[1]);
}
}
class UnZip2 {
public void unZip(String filePath, String dirPath)
// filePath是需要解压的zip文件的路径,可以是绝对或相对路径,包含文件的扩展名
// dirPath是用来放置解压后文件的目录的路径,可以是绝对或相对路径
{
File f = new File(filePath);
File dir = new File(dirPath);
filePath = f.getAbsolutePath();
System.out.println("将" + filePath + "解压到" + dir.getAbsolutePath());
if (!f.isFile())
System.out.println(filePath + "文件不存在");
else {
String zipFileName = f.getName();
System.out.println(zipFileName + "开始解压");
if (!dir.isDirectory())
dir.mkdirs(); // 创建放置解压后文件的目录
try {
ZipFile zipFile = new ZipFile(f);
Enumeration enu = zipFile.entries();
InputStream in;
FileOutputStream out;
byte buf[] = new byte[1024]; // 解压缓冲区
ZipEntry zipEntry; // 获取压缩文件中的文件或目录
String zipEntryName;
File file, parent;
int len;
while (enu.hasMoreElements()) {
zipEntry = (ZipEntry) enu.nextElement();
zipEntryName = zipEntry.getName();
System.out
.println(zipFileName + "/" + zipEntryName + "被解压");
if (zipEntry.isDirectory()) // 如果读出的是目录
new File(dir, zipEntryName).mkdirs();
else {
in = zipFile.getInputStream(zipEntry);
file = new File(dir, zipEntryName);
// 如果读出的这个文件所在目录尚未创建
parent = file.getParentFile();
if (!parent.exists())
parent.mkdirs();
// 如果该文件已存在,直接覆盖
// 如果该文件不存在,自动创建
out = new FileOutputStream(file);
while ((len = in.read(buf, 0, 1024)) != -1)
out.write(buf, 0, len);
in.close();
out.close();
}
}
zipFile.close();
System.out.println(zipFileName + "解压完毕");
} catch (Exception e) {
System.out.println(e);
System.out.println(zipFileName + "解压失败");
}
}
}
public static void main(String args[]) {
new UnZip2().unZip(args[0], args[1]);
}
}
class Zip {
public void zipFile(File f, int filesParentAbsolutePathLength,
ZipOutputStream out) throws Exception {
String filePath = f.getAbsolutePath();
System.out.println(filePath + "被压缩");
String zipEntryName = filePath.substring(filesParentAbsolutePathLength);
if (f.isDirectory()) {
ZipEntry zipEntry = new ZipEntry(zipEntryName + "/");
out.putNextEntry(zipEntry);
File temp[] = f.listFiles();
int num = temp.length;
for (int i = 0; i < num; i++)
zipFile(temp[i], filesParentAbsolutePathLength, out);
} else {
ZipEntry zipEntry = new ZipEntry(zipEntryName);
out.putNextEntry(zipEntry);
FileInputStream in = new FileInputStream(f);
byte buf[] = new byte[1024]; // 压缩缓冲区
int len;
while ((len = in.read(buf, 0, 1024)) != -1)
out.write(buf, 0, len);
in.close();
}
}
public void zip(String filePaths[], int num, String zipFilePath)
// filePaths数组存放需要压缩的文件或目录的路径,可以是绝对或相对路径,文件要包含扩展名
// zipFilePath是压缩后的zip文件的路径,可以是绝对或相对路径,包含文件的扩展名
{
File files[] = new File[num];
int i;
for (i = 0; i < num; i++) {
files[i] = new File(filePaths[i]);
filePaths[i] = files[i].getAbsolutePath();
}
File zipFile = new File(zipFilePath);
String str = "";
for (i = 0; i < num; i++) {
str += filePaths[i];
if (i < num - 1)
str += "、";
}
System.out.println("将" + str + "压缩到" + zipFile.getAbsolutePath());
File parent, temp = null;
boolean flag = true;
for (i = 0; i < num; i++) {
if (!files[i].exists()) {
System.out.println(filePaths[i] + "不存在");
flag = false;
}
if (i == 0)
temp = files[i].getAbsoluteFile().getParentFile();
else {
parent = files[i].getAbsoluteFile().getParentFile();
if (!parent.equals(temp)) {
System.out.println(filePaths[i] + "与" + filePaths[0]
+ "不在同一目录下");
flag = false;
}
}
}
if (flag) {
String zipFileName = zipFile.getName();
System.out.println("开始生成" + zipFileName);
// 如果压缩后的zip文件所在目录尚未创建
parent = zipFile.getAbsoluteFile().getParentFile();
if (!parent.exists())
parent.mkdirs();
// 对于硬盘某个分区的根目录,getAbsolutePath()方法返回值最后是"/"或"\"(如C:\)
// 对于非硬盘分区根目录的目录,getAbsolutePath()方法返回值最后是目录名,没有"/"或"\"(如C:\abc)
// 下面这段代码的作用是:
// 对于指定的绝对路径字符串,如果其最后一个字符不是"/"或"\"
// 把它变成最后一个字符是"/"或"\"的绝对路径字符串
String filesParentAbsolutePath = temp.getAbsolutePath();
int filesParentAbsolutePathLength = filesParentAbsolutePath
.length();
if (!filesParentAbsolutePath.endsWith("/")
&& !filesParentAbsolutePath.endsWith("\\"))
filesParentAbsolutePathLength++;
try {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
zipFile));
for (i = 0; i < num; i++)
zipFile(files[i], filesParentAbsolutePathLength, out);
out.close();
System.out.println(zipFileName + "生成完毕");
} catch (Exception e) {
System.out.println(e);
System.out.println(zipFileName + "生成失败");
}
}
}
public static void main(String args[]) {
int num = args.length;
new Zip().zip(args, num - 1, args[num - 1]);
}
}