java中生成和解压缩zip文件

package com.fujitsu.jsaas.fr.common.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;

import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import java.util.zip.CheckedOutputStream;

import org.apache.commons.io.FileUtils;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipFile;
import org.apache.tools.zip.ZipOutputStream;

import com.fujitsu.jsaas.fr.common.log.FRLogger;

/**
 * ファイルを圧縮したり、ZIPを解凍したりするのクラス。
 *
 * <pre>
 * ファイルを圧縮したり、ZIPを解凍したりするのクラス。 ファイルを圧縮したり、ZIPを解凍したりするAPI。
 * 変更履歴:
 *     2009/12/03 新規作成
 * </pre>
 *
 * @author 唱 春来
 * @version 1.0
 */
public final class FRZipUtility {

 /** バッファサイズ */
 private static final int BUF_SIZE = 4096;

 /**
  * ファイルエンコーディング
  */
 private static final String ENCODING = "MS932";

 /**
  * 自身のオブジェクト。
  */
 private static FRZipUtility zipUtility = new FRZipUtility();

 /**
  *コンストラクタ。
  */
 private FRZipUtility() {
 }

 /**
  * 自身のオブジェクトを返す。
  *
  * @return FRZipUtility オブジェクト
  */
 public static FRZipUtility getInstance() {
  if (FRZipUtility.zipUtility == null) {
   FRZipUtility.zipUtility = new FRZipUtility();
  }
  return FRZipUtility.zipUtility;
 }

 /**
  * 圧縮に関するのメソッド。 圧縮します。
  *
  * @param srcPath 圧縮対象フォルダパス
  * @param destPath 圧縮先フォルダパス
  * @param fileName 圧縮ファイル名
  * @return 成功の場合:true,失敗の場合:false
  */
 public static boolean compress(String srcPath, String destPath, String fileName) {
  if (srcPath == null || !new File(srcPath).exists()) {
   String[] messages = FRMessageUtility.createInstance().getTextMsgs("FR0000000015", srcPath);
   FRLogger.getInstance().output(messages, FRZipUtility.class);
   return false;
  }
  if (destPath == null || !new File(destPath).exists()) {
   String[] messages = FRMessageUtility.createInstance().getTextMsgs("FR0000000015", destPath);
   FRLogger.getInstance().output(messages, FRZipUtility.class);
   return false;
  }
  File srcPathFile = new File(srcPath);
  String zipFileName;

  if (fileName == null || fileName.length() == 0) {
   zipFileName = srcPathFile.getName() + ".zip";
  } else {
   zipFileName = fileName + ".zip";
  }
  // Zipファイル生成
  File zipFile = new File(destPath, zipFileName);
  ZipOutputStream zipOut = null;
  try {
   zipOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(zipFile)));
   zipOut.setEncoding(FRZipUtility.ENCODING);
   FRZipUtility.entryFile(zipOut, srcPathFile, "");
   // ファイルクローズ
   zipOut.close();
   return true;
  } catch (Exception e) {
   FRZipUtility.outputError("FR0000000027", srcPath, e);
   try {
    if (zipOut != null) {
     zipOut.close();
     zipOut = null;
    }
   } catch (Exception e1) {
    zipOut = null;
    FRZipUtility.outputError("FR0000000027", srcPath, e1);
   }
   // エラーが発生した場合、作成したファイルを削除
   try {
    FileUtils.forceDelete(zipFile);
   } catch (IOException e1) {
    FRZipUtility.outputError("FR0000000027", srcPath, e1);
   }
   return false;
  }
 }

 /**
  * Zipファイルを解凍に関するのメソッド。 Zipファイルを解凍します。
  *
  * @param srcPath 解凍元のフォルダパス
  * @param destPath 解凍先のフォルダパス
  * @param zipFileName zipファイル名 
  * @return 成功の場合:true,失敗の場合:false
  */
 @SuppressWarnings("unchecked")
 public static boolean decompress(String srcPath, String destPath, String zipFileName) {
  if (srcPath == null || zipFileName == null || !new File(srcPath, zipFileName).exists()) {
   String zipPath = new File(srcPath, zipFileName).getPath();
   String[] messages = FRMessageUtility.createInstance().getTextMsgs("FR0000000015", zipPath);
   FRLogger.getInstance().output(messages, FRZipUtility.class);
   return false;
  }
  if (destPath == null || !new File(destPath).exists()) {
   String[] messages = FRMessageUtility.createInstance().getTextMsgs("FR0000000015", destPath);
   FRLogger.getInstance().output(messages, FRZipUtility.class);
   return false;
  }
  // ファイルオープン
  File zip = new File(srcPath, zipFileName);
  Set<File> fileSet = new HashSet<File>();
  ZipFile zipFile = null;
  try {
   zipFile = new ZipFile(zip, FRZipUtility.ENCODING);
   Enumeration<ZipEntry> enumeration = (Enumeration<ZipEntry>) zipFile.getEntries();
   Pattern p = Pattern.compile("^.+?[/]");
   ZipEntry entry = null;
   while (enumeration.hasMoreElements()) {
    entry = enumeration.nextElement();
    String file = destPath + "/" + entry.getName();
    File f = new File(file);
    fileSet.add(f);
    Matcher m = p.matcher(entry.getName());
    if (m.find()) {
     fileSet.add(new File(destPath + "/" + entry.getName().substring(m.start(), m.end())));
    }
    if (entry.isDirectory()) {
     if (!f.exists() && !f.mkdirs()) {
      throw new Exception();
     }
    } else {
     FRZipUtility.createDir(f);
     CheckedOutputStream out = null;
     InputStream in = null;
     try {
      out = new CheckedOutputStream(new BufferedOutputStream(new FileOutputStream(f)), new CRC32());
      in = zipFile.getInputStream(entry);
      byte[] buf = new byte[FRZipUtility.BUF_SIZE];
      int writeSize = 0;
      int totalSize = 0;
      while ((writeSize = in.read(buf)) != -1) {
       totalSize += writeSize;
       out.write(buf, 0, writeSize);
      }
     } finally {
      Exception ex = null;
      if (out != null) {
       try {
        out.close();
       } catch (IOException e) {
        ex = e;
        FRZipUtility.outputError("FR0000000028", srcPath + zipFileName, e);
       }
      }
      if (in != null) {
       try {
        in.close();
       } catch (IOException e) {
        ex = e;
        FRZipUtility.outputError("FR0000000028", srcPath + zipFileName, e);
       }
      }
      if (ex != null) {
       throw ex;
      }
     }
    }
   }
   return true;
  } catch (Exception e) {
   FRZipUtility.outputError("FR0000000028", srcPath + zipFileName, e);
   // エラーが発生した場合、作成した全てのファイルを削除
   if (fileSet.size() > 0) {
    for (File f : fileSet) {
     if (f.exists()) {
      try {
       FileUtils.forceDelete(f);
      } catch (IOException e1) {
       FRZipUtility.outputError("FR0000000028", srcPath + zipFileName, e1);
      }
     }
    }
   }
   return false;
  } finally {
   if (zipFile != null) {
    try {
     zipFile.close();
    } catch (IOException e) {
     FRZipUtility.outputError("FR0000000028", srcPath + zipFileName, e);
    }
   }
  }
 }

 /**
  * 圧縮するファイルをZipファイルにエントリのメソッド。 圧縮するファイルをZipファイルにエントリします。
  *
  * @param zipOut ZipOutputStream
  * @param targetFile 登録するファイル
  * @param base 圧縮式のベースディレクトリー
  * @throws Exception 例外が発生した場合は全てスロー
  */
 private static void entryFile(ZipOutputStream zipOut, File targetFile, String base) throws Exception {

  String basepath = base;
  if ("".equals(basepath)) {
   basepath = targetFile.getName();
  }
  if (targetFile.isDirectory()) {
   basepath = basepath.length() == 0 ? "" : basepath + File.separator;
   // エントリ内容はディレクトリ
   File[] targetFiles = targetFile.listFiles();
   if (targetFiles.length == 0) {
    // エントリ内容は空のディレクトリ
    // (ファイルパスの末尾を"/"にしてエントリ)
    FRZipUtility.entry(zipOut, new File(basepath) + "/", null);
   } else {
    FRZipUtility.entry(zipOut, new File(basepath) + "/", null);
    // エントリ内容が中身のあるディレクトリの場合には
    // このディレクトリ自体はエントリせず再帰的に中身をエントリする
    for (int i = 0; i < targetFiles.length; i++) {
     FRZipUtility.entryFile(zipOut, targetFiles[i], basepath + targetFiles[i].getName());
    }
   }
  } else {
   // エントリ内容はファイル
   FRZipUtility.entry(zipOut, basepath, new FileInputStream(targetFile));
  }
 }

 /**
  * Zipファイルに登録のメソッド。 Zipファイルに登録します。
  *
  * @param zipOut ZipOutputStream
  * @param name ファイル名
  * @param is ファイルストリーム
  * @throws Exception 例外が発生した場合は全てスロー
  */
 private static void entry(ZipOutputStream zipOut, String name, InputStream is) throws Exception {
  // エントリの生成
  ZipEntry entry = new ZipEntry(name);
  zipOut.putNextEntry(entry);
  int totalSize = 0;
  if (is != null) {
   byte[] buf = new byte[FRZipUtility.BUF_SIZE];
   int readSize;
   CheckedInputStream in = new CheckedInputStream(new BufferedInputStream(is), new CRC32());
   while ((readSize = in.read(buf, 0, FRZipUtility.BUF_SIZE)) != -1) {
    totalSize += readSize;
    zipOut.write(buf, 0, readSize);
   }
   in.close();
   entry.setCrc(in.getChecksum().getValue());
  }

  // 後処理
  entry.setSize(totalSize);
  entry.setCompressedSize(totalSize);
  zipOut.closeEntry();
 }

 /**
  * ディレクトリーを新規するのメソッド。 ディレクトリーを新規する。
  *
  * @param file ファイルもしくはディレクトリー
  * @throws Exception 例外
  */
 private static void createDir(File file) throws Exception {
  if (file.isDirectory() && !file.exists()) {
   if (!file.mkdirs()) {
    throw new Exception();
   }
  } else {
   String path = file.getPath();
   int i = path.lastIndexOf(File.separator);
   path = path.substring(0, i);
   File pathFile = new File(path);
   if (!pathFile.exists() && !pathFile.mkdirs()) {
    throw new Exception();
   }
  }
 }

 /**
  * エラーログを出力する。
  *
  * @param messageId メッセージId
  * @param args ログパラメータ
  * @param e エラー
  */
 private static void outputError(String messageId, String args, Throwable e) {
  String[] messages = FRMessageUtility.createInstance().getTextMsgs(messageId, args, e.getMessage());
  FRLogger.getInstance().output(messages, e, FRZipUtility.class);
 }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值