Java/File Input Output/Copy

Материал из Java эксперт
Версия от 18:01, 31 мая 2010; (обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Copies all data from an input stream to an output stream.

  
/* 
 * Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
 * Copies all data from an input stream to an output stream.
 */
public class StreamPumper implements Runnable {
  /** the default size of the internal buffer for copying the streams */
  private static final int DEFAULT_SIZE = 1024;
  /** the input stream to pump from */
  private final InputStream is;
  /** the output stream to pmp into */
  private final OutputStream os;
  /** the size of the internal buffer for copying the streams */
  private final int size;
  /** was the end of the stream reached */
  private boolean finished;
  /** close the output stream when exhausted */
  private final boolean closeWhenExhausted;
  /**
   * Create a new stream pumper.
   * 
   * @param is
   *          input stream to read data from
   * @param os
   *          output stream to write data to.
   * @param closeWhenExhausted
   *          if true, the output stream will be closed when the input is
   *          exhausted.
   */
  public StreamPumper(final InputStream is, final OutputStream os, final boolean closeWhenExhausted) {
    this.is = is;
    this.os = os;
    this.size = DEFAULT_SIZE;
    this.closeWhenExhausted = closeWhenExhausted;
  }
  /**
   * Create a new stream pumper.
   * 
   * @param is
   *          input stream to read data from
   * @param os
   *          output stream to write data to.
   * @param closeWhenExhausted
   *          if true, the output stream will be closed when the input is
   *          exhausted.
   * @param size
   *          the size of the internal buffer for copying the streams
   */
  public StreamPumper(final InputStream is, final OutputStream os,
      final boolean closeWhenExhausted, final int size) {
    this.is = is;
    this.os = os;
    this.size = (size > 0 ? size : DEFAULT_SIZE);
    this.closeWhenExhausted = closeWhenExhausted;
  }
  /**
   * Create a new stream pumper.
   * 
   * @param is
   *          input stream to read data from
   * @param os
   *          output stream to write data to.
   */
  public StreamPumper(final InputStream is, final OutputStream os) {
    this(is, os, false);
  }
  /**
   * Copies data from the input stream to the output stream. Terminates as soon
   * as the input stream is closed or an error occurs.
   */
  public void run() {
    synchronized (this) {
      // Just in case this object is reused in the future
      finished = false;
    }
    final byte[] buf = new byte[this.size];
    int length;
    try {
      while ((length = is.read(buf)) > 0) {
        os.write(buf, 0, length);
      }
    } catch (Exception e) {
      String msg = "Got exception while reading/writing the stream";
      System.out.println(msg);
    } finally {
      if (closeWhenExhausted) {
        try {
          os.close();
        } catch (IOException e) {
          String msg = "Got exception while closing exhausted output stream";
          System.out.println(msg);
        }
      }
      synchronized (this) {
        finished = true;
        notifyAll();
      }
    }
  }
  /**
   * Tells whether the end of the stream has been reached.
   * 
   * @return true is the stream has been exhausted.
   */
  public synchronized boolean isFinished() {
    return finished;
  }
  /**
   * This method blocks until the stream pumper finishes.
   * 
   * @see #isFinished()
   */
  public synchronized void waitFor() throws InterruptedException {
    while (!isFinished()) {
      wait();
    }
  }
}





Copies file contents from source to destination

   
/** 
 * 
 * The ObjectStyle Group Software License, version 1.1
 * ObjectStyle Group - http://objectstyle.org/
 * 
 * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
 * of the software. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 
 * 3. The end-user documentation included with the redistribution, if any,
 *    must include the following acknowlegement:
 *    "This product includes software developed by independent contributors
 *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 * 
 * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
 *    or promote products derived from this software without prior written
 *    permission. For written permission, email
 *    "andrus at objectstyle dot org".
 * 
 * 5. Products derived from this software may not be called "ObjectStyle"
 *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
 *    names without prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS"" AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * 
 * This software consists of voluntary contributions made by many
 * individuals and hosted on ObjectStyle Group web site.  For more
 * information on the ObjectStyle Group, please see
 * <http://objectstyle.org/>.
 */
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.ruparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
/**
 * Contains various unorganized static utility methods used across Cayenne.
 * 
 * @author Andrei Adamchik
 */
public class Util {
  /**
   * Copies file contents from source to destination. Makes up for the lack of file
   * copying utilities in Java
   */
  public static boolean copy(File source, File destination) {
      BufferedInputStream fin = null;
      BufferedOutputStream fout = null;
      try {
          int bufSize = 8 * 1024;
          fin = new BufferedInputStream(new FileInputStream(source), bufSize);
          fout = new BufferedOutputStream(new FileOutputStream(destination), bufSize);
          copyPipe(fin, fout, bufSize);
      }
      catch (IOException ioex) {
          return false;
      }
      catch (SecurityException sx) {
          return false;
      }
      finally {
          if (fin != null) {
              try {
                  fin.close();
              }
              catch (IOException cioex) {
              }
          }
          if (fout != null) {
              try {
                  fout.close();
              }
              catch (IOException cioex) {
              }
          }
      }
      return true;
  }
  /**
   * Save URL contents to a file.
   */
  public static boolean copy(URL from, File to) {
      BufferedInputStream urlin = null;
      BufferedOutputStream fout = null;
      try {
          int bufSize = 8 * 1024;
          urlin = new BufferedInputStream(
                  from.openConnection().getInputStream(),
                  bufSize);
          fout = new BufferedOutputStream(new FileOutputStream(to), bufSize);
          copyPipe(urlin, fout, bufSize);
      }
      catch (IOException ioex) {
          return false;
      }
      catch (SecurityException sx) {
          return false;
      }
      finally {
          if (urlin != null) {
              try {
                  urlin.close();
              }
              catch (IOException cioex) {
              }
          }
          if (fout != null) {
              try {
                  fout.close();
              }
              catch (IOException cioex) {
              }
          }
      }
      return true;
  }
  /**
   * Reads data from the input and writes it to the output, until the end of the input
   * stream.
   * 
   * @param in
   * @param out
   * @param bufSizeHint
   * @throws IOException
   */
  public static void copyPipe(InputStream in, OutputStream out, int bufSizeHint)
          throws IOException {
      int read = -1;
      byte[] buf = new byte[bufSizeHint];
      while ((read = in.read(buf, 0, bufSizeHint)) >= 0) {
          out.write(buf, 0, read);
      }
      out.flush();
  }
}





Copies the contents of the given InputStream to the given OutputStream

   
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/** Utility class for working with streams.
 */
public final class Streams {
    /**
     * Default buffer size for use in
     * {@link #copy(InputStream, OutputStream, boolean)}.
     */
    private static final int DEFAULT_BUFFER_SIZE = 8192;
    /**
     * Copies the contents of the given {@link InputStream}
     * to the given {@link OutputStream}. Shortcut for
     * <pre>
     *   copy(pInputStream, pOutputStream, new byte[8192]);
     * </pre>
     * @param pInputStream The input stream, which is being read.
     * It is guaranteed, that {@link InputStream#close()} is called
     * on the stream.
     * @param pOutputStream The output stream, to which data should
     * be written. May be null, in which case the input streams
     * contents are simply discarded.
     * @param pClose True guarantees, that {@link OutputStream#close()}
     * is called on the stream. False indicates, that only
     * {@link OutputStream#flush()} should be called finally.
     *
     * @return Number of bytes, which have been copied.
     * @throws IOException An I/O error occurred.
     */
    public static long copy(InputStream pInputStream,
            OutputStream pOutputStream, boolean pClose)
            throws IOException {
        return copy(pInputStream, pOutputStream, pClose,
                new byte[DEFAULT_BUFFER_SIZE]);
    }
    /**
     * Copies the contents of the given {@link InputStream}
     * to the given {@link OutputStream}.
     * @param pIn The input stream, which is being read.
     *   It is guaranteed, that {@link InputStream#close()} is called
     *   on the stream.
     * @param pOut The output stream, to which data should
     *   be written. May be null, in which case the input streams
     *   contents are simply discarded.
     * @param pClose True guarantees, that {@link OutputStream#close()}
     *   is called on the stream. False indicates, that only
     *   {@link OutputStream#flush()} should be called finally.
     * @param pBuffer Temporary buffer, which is to be used for
     *   copying data.
     * @return Number of bytes, which have been copied.
     * @throws IOException An I/O error occurred.
     */
    public static long copy(InputStream pIn,
            OutputStream pOut, boolean pClose,
            byte[] pBuffer)
    throws IOException {
        OutputStream out = pOut;
        InputStream in = pIn;
        try {
            long total = 0;
            for (;;) {
                int res = in.read(pBuffer);
                if (res == -1) {
                    break;
                }
                if (res > 0) {
                    total += res;
                    if (out != null) {
                        out.write(pBuffer, 0, res);
                    }
                }
            }
            if (out != null) {
                if (pClose) {
                    out.close();
                } else {
                    out.flush();
                }
                out = null;
            }
            in.close();
            in = null;
            return total;
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Throwable t) {
                    /* Ignore me */
                }
            }
            if (pClose  &&  out != null) {
                try {
                    out.close();
                } catch (Throwable t) {
                    /* Ignore me */
                }
            }
        }
    }
    /**
     * This convenience method allows to read a
     * {@link org.apache.rumons.fileupload.FileItemStream}"s
     * content into a string. The platform"s default character encoding
     * is used for converting bytes into characters.
     * @param pStream The input stream to read.
     * @see #asString(InputStream, String)
     * @return The streams contents, as a string.
     * @throws IOException An I/O error occurred.
     */
    public static String asString(InputStream pStream) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        copy(pStream, baos, true);
        return baos.toString();
    }
    /**
     * This convenience method allows to read a
     * {@link org.apache.rumons.fileupload.FileItemStream}"s
     * content into a string, using the given character encoding.
     * @param pStream The input stream to read.
     * @param pEncoding The character encoding, typically "UTF-8".
     * @see #asString(InputStream)
     * @return The streams contents, as a string.
     * @throws IOException An I/O error occurred.
     */
    public static String asString(InputStream pStream, String pEncoding)
            throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        copy(pStream, baos, true);
        return baos.toString(pEncoding);
    }
}





Copies the contents of the Reader into the Writer, until the end of the stream has been reached.

  
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
/* 
 * JCommon : a free general purpose class library for the Java(tm) platform
 * 
 *
 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
 * 
 * Project Info:  http://www.jfree.org/jcommon/index.html
 *
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by 
 * the Free Software Foundation; either version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
 * USA.  
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
 * in the United States and other countries.]
 * 
 * ------------
 * IOUtils.java
 * ------------
 * (C)opyright 2002-2004, by Thomas Morgner and Contributors.
 *
 * Original Author:  Thomas Morgner;
 * Contributor(s):   David Gilbert (for Object Refinery Limited);
 *
 * $Id: IOUtils.java,v 1.8 2009/01/22 08:34:58 taqua Exp $
 *
 * Changes
 * -------
 * 26-Jan-2003 : Initial version
 * 23-Feb-2003 : Documentation
 * 25-Feb-2003 : Fixed Checkstyle issues (DG);
 * 29-Apr-2003 : Moved to jcommon
 * 04-Jan-2004 : Fixed JDK 1.2.2 issues with createRelativeURL;
 *               added support for query strings within these urls (TM);
 */

/**
 * The IOUtils provide some IO related helper methods.
 *
 * @author Thomas Morgner.
 */
public class Main {
  /**
   * Copies the contents of the Reader into the Writer, until the end of the 
   * stream has been reached.
   *
   * @param in  the reader from which to read.
   * @param out  the writer where the data is written to.
   * @param buffersize  the buffer size.
   *
   * @throws IOException if a IOError occurs.
   */
  public void copyWriter(final Reader in, final Writer out, 
          final int buffersize)
      throws IOException {
      // create a 4kbyte buffer to read the file
      final char[] bytes = new char[buffersize];
      // the input stream does not supply accurate available() data
      // the zip entry does not know the size of the data
      int bytesRead = in.read(bytes);
      while (bytesRead > -1) {
          out.write(bytes, 0, bytesRead);
          bytesRead = in.read(bytes);
      }
  }
}





Copies the contents of the Reader into the Writer, until the end of the stream has been reached. This method uses a buffer of 4096 kbyte.

  
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
/* 
 * JCommon : a free general purpose class library for the Java(tm) platform
 * 
 *
 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
 * 
 * Project Info:  http://www.jfree.org/jcommon/index.html
 *
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by 
 * the Free Software Foundation; either version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
 * USA.  
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
 * in the United States and other countries.]
 * 
 * ------------
 * IOUtils.java
 * ------------
 * (C)opyright 2002-2004, by Thomas Morgner and Contributors.
 *
 * Original Author:  Thomas Morgner;
 * Contributor(s):   David Gilbert (for Object Refinery Limited);
 *
 * $Id: IOUtils.java,v 1.8 2009/01/22 08:34:58 taqua Exp $
 *
 * Changes
 * -------
 * 26-Jan-2003 : Initial version
 * 23-Feb-2003 : Documentation
 * 25-Feb-2003 : Fixed Checkstyle issues (DG);
 * 29-Apr-2003 : Moved to jcommon
 * 04-Jan-2004 : Fixed JDK 1.2.2 issues with createRelativeURL;
 *               added support for query strings within these urls (TM);
 */

/**
 * The IOUtils provide some IO related helper methods.
 *
 * @author Thomas Morgner.
 */
public class Main {
  /**
   * Copies the contents of the Reader into the Writer, until the end of the 
   * stream has been reached. This method uses a buffer of 4096 kbyte.
   *
   * @param in the reader from which to read.
   * @param out the writer where the data is written to.
   * @throws IOException if a IOError occurs.
   */
  public void copyWriter(final Reader in, final Writer out)
      throws IOException {
      copyWriter(in, out, 4096);
  }
   /**
   * Copies the contents of the Reader into the Writer, until the end of the 
   * stream has been reached.
   *
   * @param in  the reader from which to read.
   * @param out  the writer where the data is written to.
   * @param buffersize  the buffer size.
   *
   * @throws IOException if a IOError occurs.
   */
  public void copyWriter(final Reader in, final Writer out, 
          final int buffersize)
      throws IOException {
      // create a 4kbyte buffer to read the file
      final char[] bytes = new char[buffersize];
      // the input stream does not supply accurate available() data
      // the zip entry does not know the size of the data
      int bytesRead = in.read(bytes);
      while (bytesRead > -1) {
          out.write(bytes, 0, bytesRead);
          bytesRead = in.read(bytes);
      }
  } 
}





Copies the InputStream into the OutputStream, until the end of the stream has been reached.

  
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/* 
 * JCommon : a free general purpose class library for the Java(tm) platform
 * 
 *
 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
 * 
 * Project Info:  http://www.jfree.org/jcommon/index.html
 *
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by 
 * the Free Software Foundation; either version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
 * USA.  
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
 * in the United States and other countries.]
 * 
 * ------------
 * IOUtils.java
 * ------------
 * (C)opyright 2002-2004, by Thomas Morgner and Contributors.
 *
 * Original Author:  Thomas Morgner;
 * Contributor(s):   David Gilbert (for Object Refinery Limited);
 *
 * $Id: IOUtils.java,v 1.8 2009/01/22 08:34:58 taqua Exp $
 *
 * Changes
 * -------
 * 26-Jan-2003 : Initial version
 * 23-Feb-2003 : Documentation
 * 25-Feb-2003 : Fixed Checkstyle issues (DG);
 * 29-Apr-2003 : Moved to jcommon
 * 04-Jan-2004 : Fixed JDK 1.2.2 issues with createRelativeURL;
 *               added support for query strings within these urls (TM);
 */

/**
 * The IOUtils provide some IO related helper methods.
 *
 * @author Thomas Morgner.
 */
public class Main {
  /**
   * Copies the InputStream into the OutputStream, until the end of the stream
   * has been reached.
   *
   * @param in the inputstream from which to read.
   * @param out the outputstream where the data is written to.
   * @param buffersize the buffer size.
   * @throws IOException if a IOError occurs.
   */
  public void copyStreams(final InputStream in, final OutputStream out, 
          final int buffersize) throws IOException {
      // create a 4kbyte buffer to read the file
      final byte[] bytes = new byte[buffersize];
      // the input stream does not supply accurate available() data
      // the zip entry does not know the size of the data
      int bytesRead = in.read(bytes);
      while (bytesRead > -1) {
          out.write(bytes, 0, bytesRead);
          bytesRead = in.read(bytes);
      }
  }
}





Copies the InputStream into the OutputStream, until the end of the stream has been reached. This method uses a buffer of 4096 kbyte.

  
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/* 
 * JCommon : a free general purpose class library for the Java(tm) platform
 * 
 *
 * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
 * 
 * Project Info:  http://www.jfree.org/jcommon/index.html
 *
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by 
 * the Free Software Foundation; either version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
 * USA.  
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
 * in the United States and other countries.]
 * 
 * ------------
 * IOUtils.java
 * ------------
 * (C)opyright 2002-2004, by Thomas Morgner and Contributors.
 *
 * Original Author:  Thomas Morgner;
 * Contributor(s):   David Gilbert (for Object Refinery Limited);
 *
 * $Id: IOUtils.java,v 1.8 2009/01/22 08:34:58 taqua Exp $
 *
 * Changes
 * -------
 * 26-Jan-2003 : Initial version
 * 23-Feb-2003 : Documentation
 * 25-Feb-2003 : Fixed Checkstyle issues (DG);
 * 29-Apr-2003 : Moved to jcommon
 * 04-Jan-2004 : Fixed JDK 1.2.2 issues with createRelativeURL;
 *               added support for query strings within these urls (TM);
 */

/**
 * The IOUtils provide some IO related helper methods.
 *
 * @author Thomas Morgner.
 */
public class Main {
  /**
   * Copies the InputStream into the OutputStream, until the end of the stream
   * has been reached. This method uses a buffer of 4096 kbyte.
   *
   * @param in the inputstream from which to read.
   * @param out the outputstream where the data is written to.
   * @throws IOException if a IOError occurs.
   */
  public void copyStreams(final InputStream in, final OutputStream out)
      throws IOException {
      copyStreams(in, out, 4096);
  }
  /**
   * Copies the InputStream into the OutputStream, until the end of the stream
   * has been reached.
   *
   * @param in the inputstream from which to read.
   * @param out the outputstream where the data is written to.
   * @param buffersize the buffer size.
   * @throws IOException if a IOError occurs.
   */
  public void copyStreams(final InputStream in, final OutputStream out, 
          final int buffersize) throws IOException {
      // create a 4kbyte buffer to read the file
      final byte[] bytes = new byte[buffersize];
      // the input stream does not supply accurate available() data
      // the zip entry does not know the size of the data
      int bytesRead = in.read(bytes);
      while (bytesRead > -1) {
          out.write(bytes, 0, bytesRead);
          bytesRead = in.read(bytes);
      }
  }
}





Copy a directory and all of its contents.

  
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
 Derby - Class org.apache.derby.iapi.util.PropertyUtil
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to you 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.
 */
public class Main {
  private static final int BUFFER_SIZE = 4096 * 4;
  /**
   * Copy a directory and all of its contents.
   */
  public static boolean copyDirectory(File from, File to) {
    return copyDirectory(from, to, (byte[]) null, (String[]) null);
  }
  public static boolean copyDirectory(String from, String to) {
    return copyDirectory(new File(from), new File(to));
  }
  /**
   * @param filter -
   *          array of names to not copy.
   */
  public static boolean copyDirectory(File from, File to, byte[] buffer, String[] filter) {
    //
    // System.out.println("copyDirectory("+from+","+to+")");
    if (from == null)
      return false;
    if (!from.exists())
      return true;
    if (!from.isDirectory())
      return false;
    if (to.exists()) {
      // System.out.println(to + " exists");
      return false;
    }
    if (!to.mkdirs()) {
      // System.out.println("can"t make" + to);
      return false;
    }
    String[] list = from.list();
    // Some JVMs return null for File.list() when the
    // directory is empty.
    if (list != null) {
      if (buffer == null)
        buffer = new byte[BUFFER_SIZE]; // reuse this buffer to copy files
      nextFile: for (int i = 0; i < list.length; i++) {
        String fileName = list[i];
        if (filter != null) {
          for (int j = 0; j < filter.length; j++) {
            if (fileName.equals(filter[j]))
              continue nextFile;
          }
        }
        File entry = new File(from, fileName);
        // System.out.println("\tcopying entry " + entry);
        if (entry.isDirectory()) {
          if (!copyDirectory(entry, new File(to, fileName), buffer, filter))
            return false;
        } else {
          if (!copyFile(entry, new File(to, fileName), buffer))
            return false;
        }
      }
    }
    return true;
  }
  public static boolean copyFile(File from, File to) {
    return copyFile(from, to, (byte[]) null);
  }
  public static boolean copyFile(File from, File to, byte[] buf) {
    if (buf == null)
      buf = new byte[BUFFER_SIZE];
    //
    // System.out.println("Copy file ("+from+","+to+")");
    FileInputStream from_s = null;
    FileOutputStream to_s = null;
    try {
      from_s = new FileInputStream(from);
      to_s = new FileOutputStream(to);
      for (int bytesRead = from_s.read(buf); bytesRead != -1; bytesRead = from_s.read(buf))
        to_s.write(buf, 0, bytesRead);
      from_s.close();
      from_s = null;
      to_s.getFD().sync(); // RESOLVE: sync or no sync?
      to_s.close();
      to_s = null;
    } catch (IOException ioe) {
      return false;
    } finally {
      if (from_s != null) {
        try {
          from_s.close();
        } catch (IOException ioe) {
        }
      }
      if (to_s != null) {
        try {
          to_s.close();
        } catch (IOException ioe) {
        }
      }
    }
    return true;
  }
}





Copy a file and user buffer

  
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/*
 Derby - Class org.apache.derby.iapi.util.PropertyUtil
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to you 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.
 */
public class Main {
  private static final int BUFFER_SIZE = 4096 * 4;
  /**
   * Copy a directory and all of its contents.
   */
  public static boolean copyDirectory(File from, File to) {
    return copyDirectory(from, to, (byte[]) null, (String[]) null);
  }
  public static boolean copyDirectory(String from, String to) {
    return copyDirectory(new File(from), new File(to));
  }
  /**
   * @param filter -
   *          array of names to not copy.
   */
  public static boolean copyDirectory(File from, File to, byte[] buffer, String[] filter) {
    //
    // System.out.println("copyDirectory("+from+","+to+")");
    if (from == null)
      return false;
    if (!from.exists())
      return true;
    if (!from.isDirectory())
      return false;
    if (to.exists()) {
      // System.out.println(to + " exists");
      return false;
    }
    if (!to.mkdirs()) {
      // System.out.println("can"t make" + to);
      return false;
    }
    String[] list = from.list();
    // Some JVMs return null for File.list() when the
    // directory is empty.
    if (list != null) {
      if (buffer == null)
        buffer = new byte[BUFFER_SIZE]; // reuse this buffer to copy files
      nextFile: for (int i = 0; i < list.length; i++) {
        String fileName = list[i];
        if (filter != null) {
          for (int j = 0; j < filter.length; j++) {
            if (fileName.equals(filter[j]))
              continue nextFile;
          }
        }
        File entry = new File(from, fileName);
        // System.out.println("\tcopying entry " + entry);
        if (entry.isDirectory()) {
          if (!copyDirectory(entry, new File(to, fileName), buffer, filter))
            return false;
        } else {
          if (!copyFile(entry, new File(to, fileName), buffer))
            return false;
        }
      }
    }
    return true;
  }
  public static boolean copyFile(File from, File to) {
    return copyFile(from, to, (byte[]) null);
  }
  public static boolean copyFile(File from, File to, byte[] buf) {
    if (buf == null)
      buf = new byte[BUFFER_SIZE];
    //
    // System.out.println("Copy file ("+from+","+to+")");
    FileInputStream from_s = null;
    FileOutputStream to_s = null;
    try {
      from_s = new FileInputStream(from);
      to_s = new FileOutputStream(to);
      for (int bytesRead = from_s.read(buf); bytesRead != -1; bytesRead = from_s.read(buf))
        to_s.write(buf, 0, bytesRead);
      from_s.close();
      from_s = null;
      to_s.getFD().sync(); // RESOLVE: sync or no sync?
      to_s.close();
      to_s = null;
    } catch (IOException ioe) {
      return false;
    } finally {
      if (from_s != null) {
        try {
          from_s.close();
        } catch (IOException ioe) {
        }
      }
      if (to_s != null) {
        try {
          to_s.close();
        } catch (IOException ioe) {
        }
      }
    }
    return true;
  }
}





Copy any input stream to output file

   
/**
 * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
 * 
 * Project: OpenSubsystems
 * 
 * $Id: FileUtils.java,v 1.12 2007/02/01 07:18:32 bastafidli Exp $
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License. 
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */

import java.io.BufferedInputStream;
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.io.OutputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;

/**
 * Collection of methods to make work with files easier.
 * 
 * @version $Id: FileUtils.java,v 1.12 2007/02/01 07:18:32 bastafidli Exp $
 * @author Miro Halas
 * @code.reviewer Miro Halas
 * @code.reviewed 1.7 2006/05/21 03:45:37 bastafidli
 */
public class FileUtils
{
   // Configuration settings ///////////////////////////////////////////////////
   
   /**
    * Default 10 digit file storage distribution array. This means that if I 
    * want to name file as 10 digit number e.g. number 123 as 0000000123 or 
    * number 123456789 as 01234567890. Then the path constructed from number 
    * 1234567890 using distribution 2/2/2/4 would be 12/34/56/0123456789 
    */
   public static final int[] DEFAULT_STRORAGE_TREE_DISTRIBUTION = {2, 2, 2, 4};
   
   /**
    * How big buffer to use to process files.
    */
   public static final int BUFFER_SIZE = 65536;
   
   // Cached values ////////////////////////////////////////////////////////////
   
   /**
    * Temporary directory to use. It is guarantee that it ends with \ (or /)
    */
   protected static String s_strTempDirectory;
   
   // Constructors /////////////////////////////////////////////////////////////
   
  
   
   /**
    * Move file to a new location. If the destination is on different volume,
    * this file will be copied and then original file will be deleted.
    * If the destination already exists, this method renames it with different
    * name and leaves it in that directory and moves the new file along side 
    * the renamed one.
    * 
    * @param flCurrent - file to move
    * @param flDestination - destination file
    * @throws IOException - error message
    * @throws OSSException - error message
    */
   public static void moveFile(
      File flCurrent, 
      File flDestination
   ) throws IOException
   {
      // Make sure that the source exist, it might be already moved from 
      // a directory and we just don"t know about it
      if (flCurrent.exists())
      {
         // Next check if the destination file exists
         if (flDestination.exists())
         {
            // If the destination exists, that means something went wrong
            // Rename the destination file under temporaty name and try to  
            // move the new file instead of it
          
            renameToTemporaryName(flDestination, "old");
         }
      
         // Make sure the directory exists and if not create it
         File flFolder;
         
         flFolder = flDestination.getParentFile();
         if ((flFolder != null) && (!flFolder.exists()))
         {
            if (!flFolder.mkdirs())
            {
               // Do not throw the exception if the directory already exists
               // because it was created meanwhile for example by a different 
               // thread
               if (!flFolder.exists())
               {
                  throw new IOException("Cannot create directory " + flFolder);
               }
            }
         }
         
         // Now everything should exist so try to rename the file first
         // After testing, this renames files even between volumes C to H 
         // so we don"t have to do anything else on Windows but we still
         // have to handle erro on Unix 
         if (!flCurrent.renameTo(flDestination))
         {
            // Try to copy and delete since the rename doesn"t work on Solaris
            // between file systems
            copyFile(flCurrent, flDestination);
            
            // Now delete the file
            if (!flCurrent.delete())
            {
               // Delete the destination file first since we haven"t really moved
               // the file
               flDestination.delete();
               throw new IOException("Cannot delete already copied file " + flCurrent);
            }
         }
      }   
   }
 
   /**
    * Copy the current file to the destination file.
    * 
    * @param flCurrent - source file
    * @param flDestination - destination file
    * @throws IOException - error message
    * @throws OSSException - error message
    */  
   public static void copyFile(
      File flCurrent,
      File flDestination
   ) throws IOException
   {
     // Make sure the directory exists and if not create it
     File flFolder;
     
     flFolder = flDestination.getParentFile();
     if ((flFolder != null) && (!flFolder.exists()))
     {
        if (!flFolder.mkdirs())
        {
           // Do not throw the exception if the directory already exists
           // because it was created meanwhile for example by a different 
           // thread
           if (!flFolder.exists())
           {
              throw new IOException("Cannot create directory " + flFolder);
           }
        }
     }
      // FileChannel srcChannel = null;
      // FileChannel dstChannel = null;
      FileInputStream finInput = null;
      
      //MHALAS: This code is not working reliably on Solaris 8 with 1.4.1_01
      // Getting exceptions from native code
      /*
      // Create channel on the source
      srcChannel = new FileInputStream(flCurrent).getChannel();
      // Create channel on the destination
      dstChannel = new FileOutputStream(flDestination).getChannel();
 
      // Copy file contents from source to destination
      dstChannel.transferFrom(srcChannel, 0, srcChannel.size());   
         
      Don"t forget to close the channels if you enable this code again
      */
      try
      {
         finInput = new FileInputStream(flCurrent);
      }
      catch (IOException ioExec)
      {
         if (finInput != null)
         {
            try
            {
               finInput.close();
            }
            catch (Throwable thr)
            {
              
            }
         }
         throw ioExec;
      }
      FileUtils.copyStreamToFile(finInput, flDestination);
   }
   
   /**
    * Rename the file to temporaty name with given prefix
    * 
    * @param flFileToRename - file to rename
    * @param strPrefix - prefix to use
    * @throws IOException - error message
    */
   public static void renameToTemporaryName(
      File   flFileToRename,
      String strPrefix
   ) throws IOException
   {
      assert strPrefix != null : "Prefix cannot be null.";
      
      String       strParent;
      StringBuffer sbBuffer = new StringBuffer();
      File         flTemp;
      int          iIndex = 0;
      
      strParent = flFileToRename.getParent();
      // Generate new name for the file in a deterministic way
      do
      {
         iIndex++;
         sbBuffer.delete(0, sbBuffer.length());
         if (strParent != null) 
         {
            sbBuffer.append(strParent);
            sbBuffer.append(File.separatorChar);
         }
         
         sbBuffer.append(strPrefix);
         sbBuffer.append("_");
         sbBuffer.append(iIndex);
         sbBuffer.append("_");
         sbBuffer.append(flFileToRename.getName());
               
         flTemp = new File(sbBuffer.toString());
      }      
      while (flTemp.exists());
      
      // Now we should have unique name
      if (!flFileToRename.renameTo(flTemp))
      {
         throw new IOException("Cannot rename " + flFileToRename.getAbsolutePath()
                               + " to " + flTemp.getAbsolutePath());
      }
   }
   /** 
    * Delete all files and directories in directory but do not delete the
    * directory itself.
    * 
    * @param strDir - string that specifies directory to delete
    * @return boolean - sucess flag
    */
   public static boolean deleteDirectoryContent(
      String strDir
   )
   {
      return ((strDir != null) && (strDir.length() > 0)) 
              ? deleteDirectoryContent(new File(strDir)) : false;
   }
   /** 
    * Delete all files and directories in directory but do not delete the
    * directory itself.
    * 
    * @param fDir - directory to delete
    * @return boolean - sucess flag
    */
   public static boolean deleteDirectoryContent(
      File fDir
   )
   {
      boolean bRetval = false;
      if (fDir != null && fDir.isDirectory()) 
      {
         File[] files = fDir.listFiles();
   
         if (files != null)
         {
            bRetval = true;
            boolean dirDeleted;
            
            for (int index = 0; index < files.length; index++)
            {
               if (files[index].isDirectory())
               {
                  // TODO: Performance: Implement this as a queue where you add to
                  // the end and take from the beginning, it will be more efficient
                  // than the recursion
                  dirDeleted = deleteDirectoryContent(files[index]);
                  if (dirDeleted)
                  {
                     bRetval = bRetval && files[index].delete();
                  }
                  else
                  {
                     bRetval = false;
                  }
               }
               else
               {
                  bRetval = bRetval && files[index].delete();
               }
            }
         }
      }
      return bRetval;
   }
   /**
    * Deletes all files and subdirectories under the specified directory including 
    * the specified directory
    * 
    * @param strDir - string that specifies directory to be deleted
    * @return boolean - true if directory was successfully deleted
    */
   public static boolean deleteDir(
      String strDir
   ) 
   {
      return ((strDir != null) && (strDir.length() > 0)) 
                ? deleteDir(new File(strDir)) : false;
   }
   
   /**
    * Deletes all files and subdirectories under the specified directory including 
    * the specified directory
    * 
    * @param fDir - directory to be deleted
    * @return boolean - true if directory was successfully deleted
    */
   public static boolean deleteDir(
      File fDir
   ) 
   {
      boolean bRetval = false;
      if (fDir != null && fDir.exists())
      {
         bRetval = deleteDirectoryContent(fDir);
         if (bRetval)
         {
            bRetval = bRetval && fDir.delete();         
         }
      }
      return bRetval;
   }
   
   /**
    * Compare binary files. Both files must be files (not directories) and exist.
    * 
    * @param first  - first file
    * @param second - second file
    * @return boolean - true if files are binery equal
    * @throws IOException - error in function
    */
   public boolean isFileBinaryEqual(
      File first,
      File second
   ) throws IOException
   {
      // TODO: Test: Missing test
      boolean retval = false;
      
      if ((first.exists()) && (second.exists()) 
         && (first.isFile()) && (second.isFile()))
      {
         if (first.getCanonicalPath().equals(second.getCanonicalPath()))
         {
            retval = true;
         }
         else
         {
            FileInputStream firstInput = null;
            FileInputStream secondInput = null;
            BufferedInputStream bufFirstInput = null;
            BufferedInputStream bufSecondInput = null;
            try
            {            
               firstInput = new FileInputStream(first); 
               secondInput = new FileInputStream(second);
               bufFirstInput = new BufferedInputStream(firstInput, BUFFER_SIZE); 
               bufSecondInput = new BufferedInputStream(secondInput, BUFFER_SIZE);
   
               int firstByte;
               int secondByte;
               
               while (true)
               {
                  firstByte = bufFirstInput.read();
                  secondByte = bufSecondInput.read();
                  if (firstByte != secondByte)
                  {
                     break;
                  }
                  if ((firstByte < 0) && (secondByte < 0))
                  {
                     retval = true;
                     break;
                  }
               }
            }
            finally
            {
               try
               {
                  if (bufFirstInput != null)
                  {
                     bufFirstInput.close();
                  }
               }
               finally
               {
                  if (bufSecondInput != null)
                  {
                     bufSecondInput.close();
                  }
               }
            }
         }
      }
      
      return retval;
   }

      
   /**
    * Get path which represents temporary directory. It is guarantee that it 
    * ends with \ (or /).
    * 
    * @return String
    */
   public static String getTemporaryDirectory(
   )
   {
      return s_strTempDirectory;
   }
   
   /**
    * Copy any input stream to output file. Once the data will be copied
    * the stream will be closed.
    * 
    * @param input  - InputStream to copy from
    * @param output - File to copy to
    * @throws IOException - error in function
    * @throws OSSMultiException - double error in function
    */
   public static void copyStreamToFile(
      InputStream input,
      File        output
   ) throws IOException
   {
      FileOutputStream foutOutput = null;
      // open input file as stream safe - it can throw some IOException
      try
      {
         foutOutput = new FileOutputStream(output);
      }
      catch (IOException ioExec)
      {
         if (foutOutput != null)
         {
            try
            {
               foutOutput.close();
            }
            catch (IOException ioExec2)
            {
               
            }
         }            
         
         throw ioExec;
      }
      // all streams including os are closed in copyStreamToStream function 
      // in any case
      copyStreamToStream(input, foutOutput);
   }
   /**
    * Copy any input stream to output stream. Once the data will be copied
    * both streams will be closed.
    * 
    * @param input  - InputStream to copy from
    * @param output - OutputStream to copy to
    * @throws IOException - io error in function
    * @throws OSSMultiException - double error in function
    */
   public static void copyStreamToStream(
      InputStream input,
      OutputStream output
   ) throws IOException
   {
      InputStream is = null;
      OutputStream os = null;
      int                 ch;
      try
      {
         if (input instanceof BufferedInputStream)
         {
            is = input;
         }
         else
         {
            is = new BufferedInputStream(input);
         }
         if (output instanceof BufferedOutputStream)
         {
            os = output;
         }
         else
         {
            os = new BufferedOutputStream(output);
         }
   
         while ((ch = is.read()) != -1)
         {
            os.write(ch);
         }
         os.flush();
      }
      finally
      {
         IOException exec1 = null;
         IOException exec2 = null;
         try
         {
            // because this close can throw exception we do next close in 
            // finally statement
            if (os != null)
            {
               try
               {
                  os.close();
               }
               catch (IOException exec)
               {
                  exec1 = exec;
               }
            }
         }
         finally
         {
            if (is != null)
            {
               try
               {
                  is.close();
               }
               catch (IOException exec)
               {
                  exec2 = exec;
               }
            }
         }
         if ((exec1 != null) && (exec2 != null))
         {
           throw exec1;
         }
         else if (exec1 != null)
         {
            throw exec1;
         }
         else if (exec2 != null)
         {
            throw exec2;
         }
      }
   }
}





Copy any input stream to output stream

   
/**
 * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
 * 
 * Project: OpenSubsystems
 * 
 * $Id: FileUtils.java,v 1.12 2007/02/01 07:18:32 bastafidli Exp $
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License. 
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */

import java.io.BufferedInputStream;
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.io.OutputStream;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;

/**
 * Collection of methods to make work with files easier.
 * 
 * @version $Id: FileUtils.java,v 1.12 2007/02/01 07:18:32 bastafidli Exp $
 * @author Miro Halas
 * @code.reviewer Miro Halas
 * @code.reviewed 1.7 2006/05/21 03:45:37 bastafidli
 */
public class FileUtils
{
   // Configuration settings ///////////////////////////////////////////////////
   
   /**
    * Default 10 digit file storage distribution array. This means that if I 
    * want to name file as 10 digit number e.g. number 123 as 0000000123 or 
    * number 123456789 as 01234567890. Then the path constructed from number 
    * 1234567890 using distribution 2/2/2/4 would be 12/34/56/0123456789 
    */
   public static final int[] DEFAULT_STRORAGE_TREE_DISTRIBUTION = {2, 2, 2, 4};
   
   /**
    * How big buffer to use to process files.
    */
   public static final int BUFFER_SIZE = 65536;
   
   // Cached values ////////////////////////////////////////////////////////////
   
   /**
    * Temporary directory to use. It is guarantee that it ends with \ (or /)
    */
   protected static String s_strTempDirectory;
   
   // Constructors /////////////////////////////////////////////////////////////
   
  
   
   /**
    * Move file to a new location. If the destination is on different volume,
    * this file will be copied and then original file will be deleted.
    * If the destination already exists, this method renames it with different
    * name and leaves it in that directory and moves the new file along side 
    * the renamed one.
    * 
    * @param flCurrent - file to move
    * @param flDestination - destination file
    * @throws IOException - error message
    * @throws OSSException - error message
    */
   public static void moveFile(
      File flCurrent, 
      File flDestination
   ) throws IOException
   {
      // Make sure that the source exist, it might be already moved from 
      // a directory and we just don"t know about it
      if (flCurrent.exists())
      {
         // Next check if the destination file exists
         if (flDestination.exists())
         {
            // If the destination exists, that means something went wrong
            // Rename the destination file under temporaty name and try to  
            // move the new file instead of it
          
            renameToTemporaryName(flDestination, "old");
         }
      
         // Make sure the directory exists and if not create it
         File flFolder;
         
         flFolder = flDestination.getParentFile();
         if ((flFolder != null) && (!flFolder.exists()))
         {
            if (!flFolder.mkdirs())
            {
               // Do not throw the exception if the directory already exists
               // because it was created meanwhile for example by a different 
               // thread
               if (!flFolder.exists())
               {
                  throw new IOException("Cannot create directory " + flFolder);
               }
            }
         }
         
         // Now everything should exist so try to rename the file first
         // After testing, this renames files even between volumes C to H 
         // so we don"t have to do anything else on Windows but we still
         // have to handle erro on Unix 
         if (!flCurrent.renameTo(flDestination))
         {
            // Try to copy and delete since the rename doesn"t work on Solaris
            // between file systems
            copyFile(flCurrent, flDestination);
            
            // Now delete the file
            if (!flCurrent.delete())
            {
               // Delete the destination file first since we haven"t really moved
               // the file
               flDestination.delete();
               throw new IOException("Cannot delete already copied file " + flCurrent);
            }
         }
      }   
   }
 
   /**
    * Copy the current file to the destination file.
    * 
    * @param flCurrent - source file
    * @param flDestination - destination file
    * @throws IOException - error message
    * @throws OSSException - error message
    */  
   public static void copyFile(
      File flCurrent,
      File flDestination
   ) throws IOException
   {
     // Make sure the directory exists and if not create it
     File flFolder;
     
     flFolder = flDestination.getParentFile();
     if ((flFolder != null) && (!flFolder.exists()))
     {
        if (!flFolder.mkdirs())
        {
           // Do not throw the exception if the directory already exists
           // because it was created meanwhile for example by a different 
           // thread
           if (!flFolder.exists())
           {
              throw new IOException("Cannot create directory " + flFolder);
           }
        }
     }
      // FileChannel srcChannel = null;
      // FileChannel dstChannel = null;
      FileInputStream finInput = null;
      
      //MHALAS: This code is not working reliably on Solaris 8 with 1.4.1_01
      // Getting exceptions from native code
      /*
      // Create channel on the source
      srcChannel = new FileInputStream(flCurrent).getChannel();
      // Create channel on the destination
      dstChannel = new FileOutputStream(flDestination).getChannel();
 
      // Copy file contents from source to destination
      dstChannel.transferFrom(srcChannel, 0, srcChannel.size());   
         
      Don"t forget to close the channels if you enable this code again
      */
      try
      {
         finInput = new FileInputStream(flCurrent);
      }
      catch (IOException ioExec)
      {
         if (finInput != null)
         {
            try
            {
               finInput.close();
            }
            catch (Throwable thr)
            {
              
            }
         }
         throw ioExec;
      }
      FileUtils.copyStreamToFile(finInput, flDestination);
   }
   
   /**
    * Rename the file to temporaty name with given prefix
    * 
    * @param flFileToRename - file to rename
    * @param strPrefix - prefix to use
    * @throws IOException - error message
    */
   public static void renameToTemporaryName(
      File   flFileToRename,
      String strPrefix
   ) throws IOException
   {
      assert strPrefix != null : "Prefix cannot be null.";
      
      String       strParent;
      StringBuffer sbBuffer = new StringBuffer();
      File         flTemp;
      int          iIndex = 0;
      
      strParent = flFileToRename.getParent();
      // Generate new name for the file in a deterministic way
      do
      {
         iIndex++;
         sbBuffer.delete(0, sbBuffer.length());
         if (strParent != null) 
         {
            sbBuffer.append(strParent);
            sbBuffer.append(File.separatorChar);
         }
         
         sbBuffer.append(strPrefix);
         sbBuffer.append("_");
         sbBuffer.append(iIndex);
         sbBuffer.append("_");
         sbBuffer.append(flFileToRename.getName());
               
         flTemp = new File(sbBuffer.toString());
      }      
      while (flTemp.exists());
      
      // Now we should have unique name
      if (!flFileToRename.renameTo(flTemp))
      {
         throw new IOException("Cannot rename " + flFileToRename.getAbsolutePath()
                               + " to " + flTemp.getAbsolutePath());
      }
   }
   /** 
    * Delete all files and directories in directory but do not delete the
    * directory itself.
    * 
    * @param strDir - string that specifies directory to delete
    * @return boolean - sucess flag
    */
   public static boolean deleteDirectoryContent(
      String strDir
   )
   {
      return ((strDir != null) && (strDir.length() > 0)) 
              ? deleteDirectoryContent(new File(strDir)) : false;
   }
   /** 
    * Delete all files and directories in directory but do not delete the
    * directory itself.
    * 
    * @param fDir - directory to delete
    * @return boolean - sucess flag
    */
   public static boolean deleteDirectoryContent(
      File fDir
   )
   {
      boolean bRetval = false;
      if (fDir != null && fDir.isDirectory()) 
      {
         File[] files = fDir.listFiles();
   
         if (files != null)
         {
            bRetval = true;
            boolean dirDeleted;
            
            for (int index = 0; index < files.length; index++)
            {
               if (files[index].isDirectory())
               {
                  // TODO: Performance: Implement this as a queue where you add to
                  // the end and take from the beginning, it will be more efficient
                  // than the recursion
                  dirDeleted = deleteDirectoryContent(files[index]);
                  if (dirDeleted)
                  {
                     bRetval = bRetval && files[index].delete();
                  }
                  else
                  {
                     bRetval = false;
                  }
               }
               else
               {
                  bRetval = bRetval && files[index].delete();
               }
            }
         }
      }
      return bRetval;
   }
   /**
    * Deletes all files and subdirectories under the specified directory including 
    * the specified directory
    * 
    * @param strDir - string that specifies directory to be deleted
    * @return boolean - true if directory was successfully deleted
    */
   public static boolean deleteDir(
      String strDir
   ) 
   {
      return ((strDir != null) && (strDir.length() > 0)) 
                ? deleteDir(new File(strDir)) : false;
   }
   
   /**
    * Deletes all files and subdirectories under the specified directory including 
    * the specified directory
    * 
    * @param fDir - directory to be deleted
    * @return boolean - true if directory was successfully deleted
    */
   public static boolean deleteDir(
      File fDir
   ) 
   {
      boolean bRetval = false;
      if (fDir != null && fDir.exists())
      {
         bRetval = deleteDirectoryContent(fDir);
         if (bRetval)
         {
            bRetval = bRetval && fDir.delete();         
         }
      }
      return bRetval;
   }
   
   /**
    * Compare binary files. Both files must be files (not directories) and exist.
    * 
    * @param first  - first file
    * @param second - second file
    * @return boolean - true if files are binery equal
    * @throws IOException - error in function
    */
   public boolean isFileBinaryEqual(
      File first,
      File second
   ) throws IOException
   {
      // TODO: Test: Missing test
      boolean retval = false;
      
      if ((first.exists()) && (second.exists()) 
         && (first.isFile()) && (second.isFile()))
      {
         if (first.getCanonicalPath().equals(second.getCanonicalPath()))
         {
            retval = true;
         }
         else
         {
            FileInputStream firstInput = null;
            FileInputStream secondInput = null;
            BufferedInputStream bufFirstInput = null;
            BufferedInputStream bufSecondInput = null;
            try
            {            
               firstInput = new FileInputStream(first); 
               secondInput = new FileInputStream(second);
               bufFirstInput = new BufferedInputStream(firstInput, BUFFER_SIZE); 
               bufSecondInput = new BufferedInputStream(secondInput, BUFFER_SIZE);
   
               int firstByte;
               int secondByte;
               
               while (true)
               {
                  firstByte = bufFirstInput.read();
                  secondByte = bufSecondInput.read();
                  if (firstByte != secondByte)
                  {
                     break;
                  }
                  if ((firstByte < 0) && (secondByte < 0))
                  {
                     retval = true;
                     break;
                  }
               }
            }
            finally
            {
               try
               {
                  if (bufFirstInput != null)
                  {
                     bufFirstInput.close();
                  }
               }
               finally
               {
                  if (bufSecondInput != null)
                  {
                     bufSecondInput.close();
                  }
               }
            }
         }
      }
      
      return retval;
   }

      
   /**
    * Get path which represents temporary directory. It is guarantee that it 
    * ends with \ (or /).
    * 
    * @return String
    */
   public static String getTemporaryDirectory(
   )
   {
      return s_strTempDirectory;
   }
   
   /**
    * Copy any input stream to output file. Once the data will be copied
    * the stream will be closed.
    * 
    * @param input  - InputStream to copy from
    * @param output - File to copy to
    * @throws IOException - error in function
    * @throws OSSMultiException - double error in function
    */
   public static void copyStreamToFile(
      InputStream input,
      File        output
   ) throws IOException
   {
      FileOutputStream foutOutput = null;
      // open input file as stream safe - it can throw some IOException
      try
      {
         foutOutput = new FileOutputStream(output);
      }
      catch (IOException ioExec)
      {
         if (foutOutput != null)
         {
            try
            {
               foutOutput.close();
            }
            catch (IOException ioExec2)
            {
               
            }
         }            
         
         throw ioExec;
      }
      // all streams including os are closed in copyStreamToStream function 
      // in any case
      copyStreamToStream(input, foutOutput);
   }
   /**
    * Copy any input stream to output stream. Once the data will be copied
    * both streams will be closed.
    * 
    * @param input  - InputStream to copy from
    * @param output - OutputStream to copy to
    * @throws IOException - io error in function
    * @throws OSSMultiException - double error in function
    */
   public static void copyStreamToStream(
      InputStream input,
      OutputStream output
   ) throws IOException
   {
      InputStream is = null;
      OutputStream os = null;
      int                 ch;
      try
      {
         if (input instanceof BufferedInputStream)
         {
            is = input;
         }
         else
         {
            is = new BufferedInputStream(input);
         }
         if (output instanceof BufferedOutputStream)
         {
            os = output;
         }
         else
         {
            os = new BufferedOutputStream(output);
         }
   
         while ((ch = is.read()) != -1)
         {
            os.write(ch);
         }
         os.flush();
      }
      finally
      {
         IOException exec1 = null;
         IOException exec2 = null;
         try
         {
            // because this close can throw exception we do next close in 
            // finally statement
            if (os != null)
            {
               try
               {
                  os.close();
               }
               catch (IOException exec)
               {
                  exec1 = exec;
               }
            }
         }
         finally
         {
            if (is != null)
            {
               try
               {
                  is.close();
               }
               catch (IOException exec)
               {
                  exec2 = exec;
               }
            }
         }
         if ((exec1 != null) && (exec2 != null))
         {
           throw exec1;
         }
         else if (exec1 != null)
         {
            throw exec1;
         }
         else if (exec2 != null)
         {
            throw exec2;
         }
      }
   }
}





Copy chars from a Reader to a Writer.

  
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
public class Main {
  /**
   * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
   * <p>
   * This method buffers the input internally, so there is no need to use a
   * <code>BufferedReader</code>.
   * 
   * @param input
   *          the <code>Reader</code> to read from
   * @param output
   *          the <code>Writer</code> to write to
   * @return the number of characters copied
   * @throws NullPointerException
   *           if the input or output is null
   * @throws IOException
   *           if an I/O error occurs
   * @since 1.1
   */
  public static int copy(Reader input, Writer output) throws IOException {
    char[] buffer = new char[1024];
    int count = 0;
    int n = 0;
    while (-1 != (n = input.read(buffer))) {
      output.write(buffer, 0, n);
      count += n;
    }
    return count;
  }
}





copy Completely (InputStream input, OutputStream output)

  
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.FileChannel;
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.    
 */
public class Main {
  public static void copyCompletely(InputStream input, OutputStream output) throws IOException {
    // if both are file streams, use channel IO
    if ((output instanceof FileOutputStream) && (input instanceof FileInputStream)) {
      try {
        FileChannel target = ((FileOutputStream) output).getChannel();
        FileChannel source = ((FileInputStream) input).getChannel();
        source.transferTo(0, Integer.MAX_VALUE, target);
        source.close();
        target.close();
        return;
      } catch (Exception e) { /* failover to byte stream version */
      }
    }
    byte[] buf = new byte[8192];
    while (true) {
      int length = input.read(buf);
      if (length < 0)
        break;
      output.write(buf, 0, length);
    }
    try {
      input.close();
    } catch (IOException ignore) {
    }
    try {
      output.close();
    } catch (IOException ignore) {
    }
  }
}





copy Completely (Reader input, Writer output)

  
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.    
 */
public class Main {
  public static void copyCompletely(Reader input, Writer output)
      throws IOException
  {
      char[] buf = new char[8192];
      while (true)
      {
          int length = input.read(buf);
          if (length < 0)
              break;
          output.write(buf, 0, length);
      }
      try { input.close(); } catch (IOException ignore) {}
      try { output.close(); } catch (IOException ignore) {}
  }
}





copy Completely(URI input, URI output)

  
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.net.URI;
import java.nio.channels.FileChannel;
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.    
 */
public class Main {

  public static void copyCompletely(URI input, URI output)
      throws IOException
  {
      try
      {
          InputStream in = null;
          try
          {
              File f = new File(input);
              if (f.exists())
                  in = new FileInputStream(f);
          }
          catch (Exception notAFile)
          {}
          
          File out = new File(output);
          File dir = out.getParentFile();
          dir.mkdirs();
          
          if (in == null)
              in = input.toURL().openStream();
              
          copyCompletely(in, new FileOutputStream(out));
      }
      catch (IllegalArgumentException e)
      {
          throw new IOException("Cannot copy to " + output);
      }
  }
  public static void copyCompletely(InputStream input, OutputStream output) throws IOException {
    // if both are file streams, use channel IO
    if ((output instanceof FileOutputStream) && (input instanceof FileInputStream)) {
      try {
        FileChannel target = ((FileOutputStream) output).getChannel();
        FileChannel source = ((FileInputStream) input).getChannel();
        source.transferTo(0, Integer.MAX_VALUE, target);
        source.close();
        target.close();
        return;
      } catch (Exception e) { /* failover to byte stream version */
      }
    }
    byte[] buf = new byte[8192];
    while (true) {
      int length = input.read(buf);
      if (length < 0)
        break;
      output.write(buf, 0, length);
    }
    try {
      input.close();
    } catch (IOException ignore) {
    }
    try {
      output.close();
    } catch (IOException ignore) {
    }
  }
}





Copy file and directory

   
/* 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
 * 
 * FileUtils is a collection of routines for common file system operations.
 * 
 * @author Dan Jemiolo (danj)
 * 
 */
public final class FileUtils {
  /**
   * 
   * The application"s current working directory.
   * 
   */
  public static final File CURRENT_DIR = new File(".");
  /**
   * 
   * Copies the first file or directory to the second file or directory. <br>
   * <br>
   * If the first parameter is a file and the second is a file, then the method
   * copies the contents of the first file into the second. If the second file
   * does not exist, it is created. <br>
   * <br>
   * If the first parameter is a file and the second is a directory, the file is
   * copied to the directory, overwriting any existing copy. <br>
   * <br>
   * If the first parameter is a directory and the second is a directory, the
   * first is copied underneath the second. <br>
   * <br>
   * If the first parameter is a directory and the second is a file name or does
   * not exist, a directory with that name is created, and the contents of the
   * first directory are copied there.
   * 
   * @param source
   * @param destination
   * 
   * @throws IOException
   *           <ul>
   *           <li>If the source does not exist.</li>
   *           <li>If the user does not have permission to modify the
   *           destination.</li>
   *           <li>If the copy fails for some reason related to system I/O.</li>
   *           </ul>
   * 
   */
  public static void copy(File source, File destination) throws IOException {
    if (source == null)
      throw new NullPointerException("NullSource");
    if (destination == null)
      throw new NullPointerException("NullDestination");
    if (source.isDirectory())
      copyDirectory(source, destination);
    else
      copyFile(source, destination);
  }
  public static void copyDirectory(File source, File destination) throws IOException {
    copyDirectory(source, destination, null);
  }
  public static void copyDirectory(File source, File destination, FileFilter filter)
      throws IOException {
    File nextDirectory = new File(destination, source.getName());
    //
    // create the directory if necessary...
    //
    if (!nextDirectory.exists() && !nextDirectory.mkdirs()) {
      Object[] filler = { nextDirectory.getAbsolutePath() };
      String message = "DirCopyFailed";
      throw new IOException(message);
    }
    File[] files = source.listFiles();
    //
    // and then all the items below the directory...
    //
    for (int n = 0; n < files.length; ++n) {
      if (filter == null || filter.accept(files[n])) {
        if (files[n].isDirectory())
          copyDirectory(files[n], nextDirectory, filter);
        else
          copyFile(files[n], nextDirectory);
      }
    }
  }
  public static void copyFile(File source, File destination) throws IOException {
    //
    // if the destination is a dir, what we really want to do is create
    // a file with the same name in that dir
    //
    if (destination.isDirectory())
      destination = new File(destination, source.getName());
    FileInputStream input = new FileInputStream(source);
    copyFile(input, destination);
  }
  public static void copyFile(InputStream input, File destination) throws IOException {
    OutputStream output = null;
    output = new FileOutputStream(destination);
    byte[] buffer = new byte[1024];
    int bytesRead = input.read(buffer);
    while (bytesRead >= 0) {
      output.write(buffer, 0, bytesRead);
      bytesRead = input.read(buffer);
    }
    input.close();
    output.close();
  }
}





Copy in stream to an out stream

 
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class Utils {

  /**
   * Copy in stream to an out stream
   * 
   * @param in
   * @param out
   * @throws IOException
   */
  public static void copyInputStream(InputStream in, OutputStream out) throws IOException {
      byte[] buffer = new byte[1024];
      int len = in.read(buffer);
      while (len >= 0) {
          out.write(buffer, 0, len);
          len = in.read(buffer);
      }
      in.close();
      out.close();
  }
}





Copy Pipe

   
/** 
 * 
 * The ObjectStyle Group Software License, version 1.1
 * ObjectStyle Group - http://objectstyle.org/
 * 
 * Copyright (c) 2002-2005, Andrei (Andrus) Adamchik and individual authors
 * of the software. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 * 
 * 3. The end-user documentation included with the redistribution, if any,
 *    must include the following acknowlegement:
 *    "This product includes software developed by independent contributors
 *    and hosted on ObjectStyle Group web site (http://objectstyle.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 * 
 * 4. The names "ObjectStyle Group" and "Cayenne" must not be used to endorse
 *    or promote products derived from this software without prior written
 *    permission. For written permission, email
 *    "andrus at objectstyle dot org".
 * 
 * 5. Products derived from this software may not be called "ObjectStyle"
 *    or "Cayenne", nor may "ObjectStyle" or "Cayenne" appear in their
 *    names without prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED ``AS IS"" AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE OBJECTSTYLE GROUP OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * 
 * 
 * This software consists of voluntary contributions made by many
 * individuals and hosted on ObjectStyle Group web site.  For more
 * information on the ObjectStyle Group, please see
 * <http://objectstyle.org/>.
 */
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.ruparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
/**
 * Contains various unorganized static utility methods used across Cayenne.
 * 
 * @author Andrei Adamchik
 */
public class Util {
  /**
   * Copies file contents from source to destination. Makes up for the lack of file
   * copying utilities in Java
   */
  public static boolean copy(File source, File destination) {
      BufferedInputStream fin = null;
      BufferedOutputStream fout = null;
      try {
          int bufSize = 8 * 1024;
          fin = new BufferedInputStream(new FileInputStream(source), bufSize);
          fout = new BufferedOutputStream(new FileOutputStream(destination), bufSize);
          copyPipe(fin, fout, bufSize);
      }
      catch (IOException ioex) {
          return false;
      }
      catch (SecurityException sx) {
          return false;
      }
      finally {
          if (fin != null) {
              try {
                  fin.close();
              }
              catch (IOException cioex) {
              }
          }
          if (fout != null) {
              try {
                  fout.close();
              }
              catch (IOException cioex) {
              }
          }
      }
      return true;
  }
  /**
   * Save URL contents to a file.
   */
  public static boolean copy(URL from, File to) {
      BufferedInputStream urlin = null;
      BufferedOutputStream fout = null;
      try {
          int bufSize = 8 * 1024;
          urlin = new BufferedInputStream(
                  from.openConnection().getInputStream(),
                  bufSize);
          fout = new BufferedOutputStream(new FileOutputStream(to), bufSize);
          copyPipe(urlin, fout, bufSize);
      }
      catch (IOException ioex) {
          return false;
      }
      catch (SecurityException sx) {
          return false;
      }
      finally {
          if (urlin != null) {
              try {
                  urlin.close();
              }
              catch (IOException cioex) {
              }
          }
          if (fout != null) {
              try {
                  fout.close();
              }
              catch (IOException cioex) {
              }
          }
      }
      return true;
  }
  /**
   * Reads data from the input and writes it to the output, until the end of the input
   * stream.
   * 
   * @param in
   * @param out
   * @param bufSizeHint
   * @throws IOException
   */
  public static void copyPipe(InputStream in, OutputStream out, int bufSizeHint)
          throws IOException {
      int read = -1;
      byte[] buf = new byte[bufSizeHint];
      while ((read = in.read(buf, 0, bufSizeHint)) >= 0) {
          out.write(buf, 0, read);
      }
      out.flush();
  }
}





Copy the source file system structure into the supplied target location.

 
/*
 * JBoss DNA (http://www.jboss.org/dna)
 * See the COPYRIGHT.txt file distributed with this work for information
 * regarding copyright ownership.  Some portions may be licensed
 * to Red Hat, Inc. under one or more contributor license agreements.
 * See the AUTHORS.txt file in the distribution for a full listing of 
 * individual contributors. 
 *
 * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
 * is licensed to you under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * JBoss DNA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
import java.io.BufferedInputStream;
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.io.OutputStream;
public class FileMonitor {
  /**
   * Copy the source file system structure into the supplied target location. If
   * the source is a file, the destiniation will be created as a file; if the
   * source is a directory, the destination will be created as a directory.
   * 
   * @param sourceFileOrDirectory
   *          the file or directory whose contents are to be copied into the
   *          target location
   * @param destinationFileOrDirectory
   *          the location where the copy is to be placed; does not need to
   *          exist, but if it does its type must match that of <code>src</code>
   * @return the number of files (not directories) that were copied
   * @throws IllegalArgumentException
   *           if the <code>src</code> or <code>dest</code> references are
   *           null
   * @throws IOException
   */
  public static int copy(File sourceFileOrDirectory, File destinationFileOrDirectory)
      throws IOException {
    int numberOfFilesCopied = 0;
    if (sourceFileOrDirectory.isDirectory()) {
      destinationFileOrDirectory.mkdirs();
      String list[] = sourceFileOrDirectory.list();
      for (int i = 0; i < list.length; i++) {
        String dest1 = destinationFileOrDirectory.getPath() + File.separator + list[i];
        String src1 = sourceFileOrDirectory.getPath() + File.separator + list[i];
        numberOfFilesCopied += copy(new File(src1), new File(dest1));
      }
    } else {
      InputStream fin = new FileInputStream(sourceFileOrDirectory);
      fin = new BufferedInputStream(fin);
      try {
        OutputStream fout = new FileOutputStream(destinationFileOrDirectory);
        fout = new BufferedOutputStream(fout);
        try {
          int c;
          while ((c = fin.read()) >= 0) {
            fout.write(c);
          }
        } finally {
          fout.close();
        }
      } finally {
        fin.close();
      }
      numberOfFilesCopied++;
    }
    return numberOfFilesCopied;
  }
}





Utility methods for file and stream copying

    
/*
 * Copyright 2002-2005 the original author or authors.
 * 
 * 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.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
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.io.Reader;
import java.io.StringWriter;
import java.io.Writer;

/**
 * Simple utility methods for file and stream copying.
 * All copy methods use a block size of 4096 bytes,
 * and close all affected streams when done.
 *
 * <p>Mainly for use within the framework,
 * but also useful for application code.
 *
 * @author Juergen Hoeller
 * @since 06.10.2003
 */
public abstract class FileCopyUtils {
  public static final int BUFFER_SIZE = 4096;

  //---------------------------------------------------------------------
  // Copy methods for java.io.File
  //---------------------------------------------------------------------
  /**
   * Copy the contents of the given input File to the given output File.
   * @param in the file to copy from
   * @param out the file to copy to
   * @return the number of bytes copied
   * @throws IOException in case of I/O errors
   */
  public static int copy(File in, File out) throws IOException {
    return copy(new BufferedInputStream(new FileInputStream(in)),
        new BufferedOutputStream(new FileOutputStream(out)));
  }
  /**
   * Copy the contents of the given byte array to the given output File.
   * @param in the byte array to copy from
   * @param out the file to copy to
   * @throws IOException in case of I/O errors
   */
  public static void copy(byte[] in, File out) throws IOException {
    
    ByteArrayInputStream inStream = new ByteArrayInputStream(in);
    OutputStream outStream = new BufferedOutputStream(new FileOutputStream(out));
    copy(inStream, outStream);
  }
  /**
   * Copy the contents of the given input File into a new byte array.
   * @param in the file to copy from
   * @return the new byte array that has been copied to
   * @throws IOException in case of I/O errors
   */
  public static byte[] copyToByteArray(File in) throws IOException {
  
    return copyToByteArray(new BufferedInputStream(new FileInputStream(in)));
  }

  //---------------------------------------------------------------------
  // Copy methods for java.io.InputStream / java.io.OutputStream
  //---------------------------------------------------------------------
  /**
   * Copy the contents of the given InputStream to the given OutputStream.
   * Closes both streams when done.
   * @param in the stream to copy from
   * @param out the stream to copy to
   * @return the number of bytes copied
   * @throws IOException in case of I/O errors
   */
  public static int copy(InputStream in, OutputStream out) throws IOException {
    try {
      int byteCount = 0;
      byte[] buffer = new byte[BUFFER_SIZE];
      int bytesRead = -1;
      while ((bytesRead = in.read(buffer)) != -1) {
        out.write(buffer, 0, bytesRead);
        byteCount += bytesRead;
      }
      out.flush();
      return byteCount;
    }
    finally {
      try {
        in.close();
        out.close();
      }
      catch (IOException ex) {
        System.out.println("Could not close OutputStream:" + ex);
      }
    }
  }
  /**
   * Copy the contents of the given byte array to the given OutputStream.
   * Closes the stream when done.
   * @param in the byte array to copy from
   * @param out the OutputStream to copy to
   * @throws IOException in case of I/O errors
   */
  public static void copy(byte[] in, OutputStream out) throws IOException {
    try {
      out.write(in);
    }
    finally {
      try {
        out.close();
      }
      catch (IOException ex) {
        System.out.println("Could not close OutputStream:"+ ex);
      }
    }
  }
  /**
   * Copy the contents of the given InputStream into a new byte array.
   * Closes the stream when done.
   * @param in the stream to copy from
   * @return the new byte array that has been copied to
   * @throws IOException in case of I/O errors
   */
  public static byte[] copyToByteArray(InputStream in) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream(BUFFER_SIZE);
    copy(in, out);
    return out.toByteArray();
  }

  //---------------------------------------------------------------------
  // Copy methods for java.io.Reader / java.io.Writer
  //---------------------------------------------------------------------
  /**
   * Copy the contents of the given Reader to the given Writer.
   * Closes both when done.
   * @param in the Reader to copy from
   * @param out the Writer to copy to
   * @return the number of characters copied
   * @throws IOException in case of I/O errors
   */
  public static int copy(Reader in, Writer out) throws IOException {
    try {
      int byteCount = 0;
      char[] buffer = new char[BUFFER_SIZE];
      int bytesRead = -1;
      while ((bytesRead = in.read(buffer)) != -1) {
        out.write(buffer, 0, bytesRead);
        byteCount += bytesRead;
      }
      out.flush();
      return byteCount;
    }
    finally {
      try {
        in.close();
      }
      catch (IOException ex) {
        System.out.println("Could not close Reader" + ex);
      }
      try {
        out.close();
      }
      catch (IOException ex) {
        System.out.println("Could not close Writer:" + ex);
      }
    }
  }
  /**
   * Copy the contents of the given String to the given output Writer.
   * Closes the write when done.
   * @param in the String to copy from
   * @param out the Writer to copy to
   * @throws IOException in case of I/O errors
   */
  public static void copy(String in, Writer out) throws IOException {
    try {
      out.write(in);
    }
    finally {
      try {
        out.close();
      }
      catch (IOException ex) {
        System.out.println("Could not close Writer" + ex);
      }
    }
  }
  /**
   * Copy the contents of the given Reader into a String.
   * Closes the reader when done.
   * @param in the reader to copy from
   * @return the String that has been copied to
   * @throws IOException in case of I/O errors
   */
  public static String copyToString(Reader in) throws IOException {
    StringWriter out = new StringWriter();
    copy(in, out);
    return out.toString();
  }
}