commons compress使用+ziji

来源:互联网 发布:淘宝猛犸象牙 编辑:程序博客网 时间:2024/05/19 17:49

此文介绍apache的压缩包,好处是可以自己设置ZipFile文件名的编码.

而jdk自带的ZipFIle只支持utf-8,导致压缩后中文出现乱码.

 

*下面给出个zip压缩解压的示例

---zip压缩

private void doZip() throws ArchiveException, IOException{ZipArchiveOutputStream zos =(ZipArchiveOutputStream) new ArchiveStreamFactory().createArchiveOutputStream("zip", new FileOutputStream(path)); //or new ZipArchiveOutputStream(new FileOutputStream(path)) zos.setEncoding(encoding);String rootPath =FileUtil.getRootPath(files);  //获取要压缩文件根路径ZipArchiveEntry ze;for(File f:files){if(!f.exists())continue;ze =new ZipArchiveEntry(getEntryName(f,rootPath)); //获取每个文件相对路径,作为在ZIP中路径zos.putArchiveEntry(ze);//folderif(ze.isDirectory()){zos.closeArchiveEntry();continue;}//fileFileInputStream fis =new FileInputStream(f);IOUtils.copy(fis, zos, BUF);fis.close();zos.closeArchiveEntry();}zos.close();}private String getEntryName(File f,String rootPath){String entryName;String fPath =f.getAbsolutePath();if(fPath.indexOf(rootPath)!=-1)entryName =fPath.substring(rootPath.length()+1);elseentryName =f.getName();if(f.isDirectory())entryName +="/";   //"/"后缀表示entry是文件夹return entryName;}

 

---zip解压

public void doZip() throws IOException, ArchiveException{ZipFile file =new ZipFile(sPath,encoding);Enumeration<ZipArchiveEntry> en =file.getEntries();ZipArchiveEntry ze;while(en.hasMoreElements()){ze =en.nextElement();File f =new File(tPath,ze.getName());        //创建完整路径if(ze.isDirectory()){    f.mkdirs();continue;}elsef.getParentFile().mkdirs();   InputStream is =file.getInputStream(ze);OutputStream os =new FileOutputStream(f);IOUtils.copy(is, os, BUF);is.close();os.close();}file.close();}//这是更一般的解压处理public void doTar() throws IOException{TarArchiveInputStream tis =new TarArchiveInputStream(new FileInputStream(sPath));TarArchiveEntry te =null;while((te=tis.getNextTarEntry())!=null){       File target =new File(tPath,te.getName());if(te.isDirectory()){target.mkdirs();continue;}elsetarget.getParentFile().mkdirs();FileOutputStream fos =new FileOutputStream(target); //将当前entry写入文件byte[] buf =new byte[BUF];int len;while((len=tis.read(buf))!=-1){fos.write(buf, 0, len);}fos.close();}tis.close();}

 

*tar包

---默认tar中entry的长度限制是TarConstants.NAMELEN = 100 [0x64]

原因有待研究?

这个长度应当=操作系统支持的最小长度.

---长文件名处理setLongFileMode(int longFileMode)

参数

/** Fail if a long file name is required in the archive. */
public static final int LONGFILE_ERROR = 0;

/** Long paths will be truncated in the archive. */
public static final int LONGFILE_TRUNCATE = 1;

/** GNU tar extensions are used to store long file names in the archive. */
public static final int LONGFILE_GNU = 2;

在putArchiveEntry()中根据上面的设置处理文件名.

使用长文件名的设置缺点是在其他非gnu操作系统上可能无法解压

"If you choose the GNU tar option, the archive can not be extracted using many other tar implementations like the ones of OpenBSD, Solaris or MacOS X"

---注意

"The tar package does not support the full POSIX tar standard nor more modern GNU extension of said standard. It cannot deal with entries larger than 2 GByte either. "

 

*Jar包

“Note that ArchiveStreamFactory doesn't distinguish ZIP archives from JAR archives, so if you use the one-argument createArchiveInputStream  method on a JAR archive, it will still return the more generic ZipArchiveInputStream.

The JarArchiveEntry class contains fields for certificates and attributes that are planned to be supported in the future but are not supported as of Compress 1.0.”

从源码可知JarArchive*Stream和JarArchiveEntry继承自对应的Zip,从说明可知,目前两者功能是一致的

package com.me;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;

import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.apache.commons.compress.utils.IOUtils;

public class UnZip {
 
 private static final String path = "D://WorkSpace//111.zip";
 
 private static final String tpath = "D://WorkSpace//";
 
 public static void main(String[] args) throws IOException
 {
  //File file = new File(path);
  ZipFile zipFile = new ZipFile(path);
  Enumeration<ZipArchiveEntry> en = zipFile.getEntries();
  ZipArchiveEntry ze;
  while(en.hasMoreElements())
  {
   ze = en.nextElement();
   File file = new File(tpath,ze.getName());
   //创建完整路径
   if(ze.isDirectory())
   {
    file.mkdirs();
    continue;
   }else{
    file.getParentFile().mkdirs();
   }
   InputStream is =zipFile.getInputStream(ze);
   OutputStream os =new FileOutputStream(file);
   IOUtils.copy(is, os);
   is.close();
   os.close();
  }
  zipFile.close();  
 }
}

原创粉丝点击