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 io.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   * @throws IOException in case of I/O errors
109   */
110  private static void copy(InputStream in, OutputStream out) throws IOException {
111    try {
112      int byteCount = 0;
113      byte[] buffer = new byte[4096];
114      int bytesRead;
115      while ((bytesRead = in.read(buffer)) != -1) {
116        out.write(buffer, 0, bytesRead);
117        byteCount += bytesRead;
118      }
119      out.flush();
120    } finally {
121      try {
122        in.close();
123      } catch (IOException ex) {
124        //Ignore
125      }
126      try {
127        out.close();
128      } catch (IOException ex) {
129        //Ignore
130      }
131    }
132  }
133}