欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java实现的zip工具类完整实例

程序员文章站 2024-03-02 13:22:52
本文实例讲述了java实现的zip工具类。分享给大家供大家参考,具体如下: 实现把zip解压到指定路径,把文件夹压缩到zip,把文件列表压缩为zip的三个方法...

本文实例讲述了java实现的zip工具类。分享给大家供大家参考,具体如下:

实现把zip解压到指定路径,把文件夹压缩到zip,把文件列表压缩为zip的三个方法

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 java.nio.charset.charset;
import java.util.arraylist;
import java.util.enumeration;
import java.util.list;
import java.util.zip.zipentry;
import java.util.zip.zipfile;
import java.util.zip.zipoutputstream;
public class ziputils
{
  /**
   * 解压zip到指定路径
   * @param zipfile 待解压文件
   * @param descdir 指定解压路径
   * @return filenames 解压的全部文件名
   * @throws ioexception
   */
  public static list<string> unzipfiles(file zipfile, string descdir) throws ioexception
 { 
    list<string> filenames = new arraylist<string>();
  zipfile zip = new zipfile(zipfile,charset.forname("gbk"));//解决中文文件夹乱码 
  string name = zip.getname().substring(zip.getname().lastindexof('\\')+1, zip.getname().lastindexof('.')); 
  file pathfile = new file(descdir+name); 
  if (!pathfile.exists()) 
  { 
   pathfile.mkdirs(); 
  } 
  string outpath = "";
  for (enumeration<? extends zipentry> entries = zip.entries(); entries.hasmoreelements();)
  { 
   zipentry entry = (zipentry) entries.nextelement(); 
   string zipentryname = entry.getname(); 
   filenames.add(zipentryname);
   inputstream in = zip.getinputstream(entry); 
   outpath = (descdir + name +"/"+ zipentryname).replaceall("\\*", "/"); 
   // 判断路径是否存在,不存在则创建文件路径 
   file file = new file(outpath.substring(0, outpath.lastindexof('/'))); 
   if (!file.exists()) 
   { 
    file.mkdirs(); 
   } 
   // 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压 
   if (new file(outpath).isdirectory()) 
   { 
    continue; 
   } 
   // 输出文件路径信息 
   fileoutputstream out = new fileoutputstream(outpath); 
   byte[] buf1 = new byte[1024]; 
   int len; 
   while ((len = in.read(buf1)) > 0) { 
    out.write(buf1, 0, len); 
   } 
   in.close(); 
   out.close(); 
  } 
  pathfile.delete();
  return filenames; 
 }
  /**
   * 压缩文件夹成zip
   * @param srcdir 待打包的文件夹路径
   * @param out 打包文件名及存储路径
   * @param keepdirstructure 是否保留文件夹结构 不保留则把文件夹下全部文件都打压在一起
   * @throws runtimeexception
   */
  public static void doctozip(string srcdir, outputstream out, boolean keepdirstructure)throws runtimeexception
  {
    long start = system.currenttimemillis();
    zipoutputstream zos = null ;
    try 
    {
      zos = new zipoutputstream(out);
      file sourcefile = new file(srcdir);
      compress(sourcefile,zos,sourcefile.getname(),keepdirstructure);
      long end = system.currenttimemillis();
      system.out.println("压缩完成,耗时:" + (end - start) +" ms");
    } catch (exception e) 
    {
      throw new runtimeexception("zip error from ziputils",e);
    }finally
    {
      if(zos != null)
      {
        try 
        {
          zos.close();
        } catch (ioexception e)
        {
          e.printstacktrace();
        }
      }
    }
  }
  /**
   * 压缩成zip 将多个文件大包
   * @param srcfiles 需要压缩的文件列表
   * @param out     压缩文件输出流
   * @throws runtimeexception 压缩失败会抛出运行时异常
   */
  public static void filestozip(list<file> srcfiles , outputstream out)throws runtimeexception 
  {
    long start = system.currenttimemillis();
    zipoutputstream zos = null ;
    int buffer_size = 2 * 1024;
    try 
    {
      zos = new zipoutputstream(out);
      for (file srcfile : srcfiles) 
      {
        byte[] buf = new byte[buffer_size];
        zos.putnextentry(new zipentry(srcfile.getname()));
        int len;
        fileinputstream in = new fileinputstream(srcfile);
        while ((len = in.read(buf)) != -1)
        {
          zos.write(buf, 0, len);
        }
        zos.closeentry();
        in.close();
      }
      long end = system.currenttimemillis();
      system.out.println("压缩完成,耗时:" + (end - start) +" ms");
    } catch (exception e) 
    {
      throw new runtimeexception("zip error from ziputils",e);
    }finally
    {
      if(zos != null)
      {
        try 
        {
          zos.close();
        } catch (ioexception e)
        {
          e.printstacktrace();
        }
      }
    }
  }
  /**
   * 递归压缩方法
   * @param sourcefile 源文件
   * @param zos     zip输出流
   * @param name     压缩后的名称
   * @param keepdirstructure 是否保留原来的目录结构,true:保留目录结构; 
   *               false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
   * @throws exception
   */
  private static void compress(file sourcefile, zipoutputstream zos, string name,
      boolean keepdirstructure) throws exception
  {
    int buffer_size = 2 * 1024;
    byte[] buf = new byte[buffer_size];
    if(sourcefile.isfile())
    {
      // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
      zos.putnextentry(new zipentry(name));
      // copy文件到zip输出流中
      int len;
      fileinputstream in = new fileinputstream(sourcefile);
      while ((len = in.read(buf)) != -1)
      {
        zos.write(buf, 0, len);
      }
      // complete the entry
      zos.closeentry();
      in.close();
    } else
    {
      file[] listfiles = sourcefile.listfiles();
      if(listfiles == null || listfiles.length == 0)
      {
        // 需要保留原来的文件结构时,需要对空文件夹进行处理
        if(keepdirstructure)
        {
          // 空文件夹的处理
          zos.putnextentry(new zipentry(name + "/"));
          // 没有文件,不需要文件的copy
          zos.closeentry();
        }
      }else 
      {
        for (file file : listfiles) 
        {
          // 判断是否需要保留原来的文件结构
          if (keepdirstructure) 
          {
            // 注意:file.getname()前面需要带上父文件夹的名字加一斜杠,
            // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
            compress(file, zos, name + "/" + file.getname(),keepdirstructure);
          } else 
          {
            compress(file, zos, file.getname(),keepdirstructure);
          }
        }
      }
    }
  }
}

更多关于java算法相关内容感兴趣的读者可查看本站专题:《java文件与目录操作技巧汇总》、《java数据结构与算法教程》、《java操作dom节点技巧总结》和《java缓存操作技巧汇总

希望本文所述对大家java程序设计有所帮助。