001/**
002 * Copyright 2010-2016 Boxfuse GmbH
003 * <p/>
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 * <p/>
008 * http://www.apache.org/licenses/LICENSE-2.0
009 * <p/>
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.avaje.classpath.scanner.internal;
017
018import java.io.ByteArrayOutputStream;
019import java.io.IOException;
020import java.io.InputStream;
021import java.io.OutputStream;
022import java.io.Reader;
023import java.io.StringWriter;
024import java.io.Writer;
025
026/**
027 * Utility class for copying files and their contents. Inspired by Spring's own.
028 */
029public class FileCopyUtils {
030  /**
031   * Prevent instantiation.
032   */
033  private FileCopyUtils() {
034    // Do nothing
035  }
036
037  /**
038   * Copy the contents of the given Reader into a String.
039   * Closes the reader when done.
040   *
041   * @param in the reader to copy from
042   * @return the String that has been copied to
043   * @throws IOException in case of I/O errors
044   */
045  public static String copyToString(Reader in) throws IOException {
046    StringWriter out = new StringWriter();
047    copy(in, out);
048    String str = out.toString();
049
050    //Strip UTF-8 BOM if necessary
051    if (str.startsWith("\ufeff")) {
052      return str.substring(1);
053    }
054
055    return str;
056  }
057
058  /**
059   * Copy the contents of the given InputStream into a new byte array.
060   * Closes the stream when done.
061   *
062   * @param in the stream to copy from
063   * @return the new byte array that has been copied to
064   * @throws IOException in case of I/O errors
065   */
066  public static byte[] copyToByteArray(InputStream in) throws IOException {
067    ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
068    copy(in, out);
069    return out.toByteArray();
070  }
071
072  /**
073   * Copy the contents of the given Reader to the given Writer.
074   * Closes both when done.
075   *
076   * @param in  the Reader to copy from
077   * @param out the Writer to copy to
078   * @throws IOException in case of I/O errors
079   */
080  private static void copy(Reader in, Writer out) throws IOException {
081    try {
082      char[] buffer = new char[4096];
083      int bytesRead;
084      while ((bytesRead = in.read(buffer)) != -1) {
085        out.write(buffer, 0, bytesRead);
086      }
087      out.flush();
088    } finally {
089      try {
090        in.close();
091      } catch (IOException ex) {
092        //Ignore
093      }
094      try {
095        out.close();
096      } catch (IOException ex) {
097        //Ignore
098      }
099    }
100  }
101
102  /**
103   * Copy the contents of the given InputStream to the given OutputStream.
104   * Closes both streams when done.
105   *
106   * @param in  the stream to copy from
107   * @param out the stream to copy to
108   * @return the number of bytes copied
109   * @throws IOException in case of I/O errors
110   */
111  private static int copy(InputStream in, OutputStream out) throws IOException {
112    try {
113      int byteCount = 0;
114      byte[] buffer = new byte[4096];
115      int bytesRead;
116      while ((bytesRead = in.read(buffer)) != -1) {
117        out.write(buffer, 0, bytesRead);
118        byteCount += bytesRead;
119      }
120      out.flush();
121      return byteCount;
122    } finally {
123      try {
124        in.close();
125      } catch (IOException ex) {
126        //Ignore
127      }
128      try {
129        out.close();
130      } catch (IOException ex) {
131        //Ignore
132      }
133    }
134  }
135}