File Input Output Java

/*   Copyright 2004 The Apache Software Foundation
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *  limitations under the License.
 */
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.jar.JarOutputStream;
/**
 * Provides utility services for jarring and unjarring files and directories.
 * Note that a given instance of JarHelper is not threadsafe with respect to
 * multiple jar operations.
 * 
 * @author Patrick Calahan 
 */
public class JarHelper {
  // Constants
  private static final int BUFFER_SIZE = 2156;
  // Variables
  private byte[] mBuffer = new byte[BUFFER_SIZE];
  private int mByteCount = 0;
  private boolean mVerbose = false;
  private String mDestJarName = "";
  // Constructor
  /**
   * Instantiates a new JarHelper.
   */
  public JarHelper() {
  }
  // Public methods
  /**
   * Jars a given directory or single file into a JarOutputStream.
   */
  public void jarDir(File dirOrFile2Jar, File destJar) throws IOException {
    if (dirOrFile2Jar == null || destJar == null)
      throw new IllegalArgumentException();
    mDestJarName = destJar.getCanonicalPath();
    FileOutputStream fout = new FileOutputStream(destJar);
    JarOutputStream jout = new JarOutputStream(fout);
    // jout.setLevel(0);
    try {
      jarDir(dirOrFile2Jar, jout, null);
    } catch (IOException ioe) {
      throw ioe;
    } finally {
      jout.close();
      fout.close();
    }
  }
  /**
   * Unjars a given jar file into a given directory.
   */
  public void unjarDir(File jarFile, File destDir) throws IOException {
    BufferedOutputStream dest = null;
    FileInputStream fis = new FileInputStream(jarFile);
    unjar(fis, destDir);
  }
  /**
   * Given an InputStream on a jar file, unjars the contents into the given
   * directory.
   */
  public void unjar(InputStream in, File destDir) throws IOException {
    BufferedOutputStream dest = null;
    JarInputStream jis = new JarInputStream(in);
    JarEntry entry;
    while ((entry = jis.getNextJarEntry()) != null) {
      if (entry.isDirectory()) {
        File dir = new File(destDir, entry.getName());
        dir.mkdir();
        if (entry.getTime() != -1)
          dir.setLastModified(entry.getTime());
        continue;
      }
      int count;
      byte data[] = new byte[BUFFER_SIZE];
      File destFile = new File(destDir, entry.getName());
      if (mVerbose)
        System.out.println("unjarring " + destFile + " from " + entry.getName());
      FileOutputStream fos = new FileOutputStream(destFile);
      dest = new BufferedOutputStream(fos, BUFFER_SIZE);
      while ((count = jis.read(data, 0, BUFFER_SIZE)) != -1) {
        dest.write(data, 0, count);
      }
      dest.flush();
      dest.close();
      if (entry.getTime() != -1)
        destFile.setLastModified(entry.getTime());
    }
    jis.close();
  }
  public void setVerbose(boolean b) {
    mVerbose = b;
  }
  // Private methods
  private static final char SEP = '/';
  /**
   * Recursively jars up the given path under the given directory.
   */
  private void jarDir(File dirOrFile2jar, JarOutputStream jos, String path) throws IOException {
    if (mVerbose)
      System.out.println("checking " + dirOrFile2jar);
    if (dirOrFile2jar.isDirectory()) {
      String[] dirList = dirOrFile2jar.list();
      String subPath = (path == null) ? "" : (path + dirOrFile2jar.getName() + SEP);
      if (path != null) {
        JarEntry je = new JarEntry(subPath);
        je.setTime(dirOrFile2jar.lastModified());
        jos.putNextEntry(je);
        jos.flush();
        jos.closeEntry();
      }
      for (int i = 0; i < dirList.length; i++) {
        File f = new File(dirOrFile2jar, dirList[i]);
        jarDir(f, jos, subPath);
      }
    } else {
      if (dirOrFile2jar.getCanonicalPath().equals(mDestJarName)) {
        if (mVerbose)
          System.out.println("skipping " + dirOrFile2jar.getPath());
        return;
      }
      if (mVerbose)
        System.out.println("adding " + dirOrFile2jar.getPath());
      FileInputStream fis = new FileInputStream(dirOrFile2jar);
      try {
        JarEntry entry = new JarEntry(path + dirOrFile2jar.getName());
        entry.setTime(dirOrFile2jar.lastModified());
        jos.putNextEntry(entry);
        while ((mByteCount = fis.read(mBuffer)) != -1) {
          jos.write(mBuffer, 0, mByteCount);
          if (mVerbose)
            System.out.println("wrote " + mByteCount + " bytes");
        }
        jos.flush();
        jos.closeEntry();
      } catch (IOException ioe) {
        throw ioe;
      } finally {
        fis.close();
      }
    }
  }
  // for debugging
  public static void main(String[] args) throws IOException {
    if (args.length < 2) {
      System.err.println("Usage: JarHelper jarname.jar directory");
      return;
    }
    JarHelper jarHelper = new JarHelper();
    jarHelper.mVerbose = true;
    File destJar = new File(args[0]);
    File dirOrFile2Jar = new File(args[1]);
    jarHelper.jarDir(dirOrFile2Jar, destJar);
  }
}