`
yefei
  • 浏览: 123372 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

ZIP压缩文件的解压

F# 
阅读更多

//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]);
 }
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics