View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  package org.apache.commons.fileupload.util;
    18
    19  import java.io.ByteArrayOutputStream;
    20  import java.io.IOException;
    21  import java.io.InputStream;
    22  import java.io.OutputStream;
    23
    24  import org.apache.commons.fileupload.InvalidFileNameException;
    25  import org.apache.commons.io.IOUtils;
    26
    27  /**
    28   * Utility class for working with streams.
    29   */
    30  public final class Streams {
    31
    32      /**
    33       * Private constructor, to prevent instantiation.
    34       * This class has only static methods.
    35       */
    36      private Streams() {
    37          // Does nothing
    38      }
    39
    40      /**
    41       * Default buffer size for use in
    42       * {@link #copy(InputStream, OutputStream, boolean)}.
    43       */
    44      private static final int DEFAULT_BUFFER_SIZE = 8192;
    45
    46      /**
    47       * Copies the contents of the given {@link InputStream}
    48       * to the given {@link OutputStream}. Shortcut for
    49       * <pre>
    50       *   copy(pInputStream, pOutputStream, new byte[8192]);
    51       * </pre>
    52       *
    53       * @param inputStream The input stream, which is being read.
    54       * It is guaranteed, that {@link InputStream#close()} is called
    55       * on the stream.
    56       * @param outputStream The output stream, to which data should
    57       * be written. May be null, in which case the input streams
    58       * contents are simply discarded.
    59       * @param closeOutputStream True guarantees, that {@link OutputStream#close()}
    60       * is called on the stream. False indicates, that only
    61       * {@link OutputStream#flush()} should be called finally.
    62       *
    63       * @return Number of bytes, which have been copied.
    64       * @throws IOException An I/O error occurred.
    65       */
    66      public static long copy(InputStream inputStream, OutputStream outputStream, boolean closeOutputStream)
    67              throws IOException {
    68          return copy(inputStream, outputStream, closeOutputStream, new byte[DEFAULT_BUFFER_SIZE]);
    69      }
    70
    71      /**
    72       * Copies the contents of the given {@link InputStream}
    73       * to the given {@link OutputStream}.
    74       *
    75       * @param inputStream The input stream, which is being read.
    76       *   It is guaranteed, that {@link InputStream#close()} is called
    77       *   on the stream.
    78       * @param outputStream The output stream, to which data should
    79       *   be written. May be null, in which case the input streams
    80       *   contents are simply discarded.
    81       * @param closeOutputStream True guarantees, that {@link OutputStream#close()}
    82       *   is called on the stream. False indicates, that only
    83       *   {@link OutputStream#flush()} should be called finally.
    84       * @param buffer Temporary buffer, which is to be used for
    85       *   copying data.
    86       * @return Number of bytes, which have been copied.
    87       * @throws IOException An I/O error occurred.
    88       */
    89      public static long copy(InputStream inputStream,
    90              OutputStream outputStream, boolean closeOutputStream,
    91              byte[] buffer)
    92      throws IOException {
    93          OutputStream out = outputStream;
    94          InputStream in = inputStream;
    95          try {
    96              long total = 0;
    97              for (;;) {
    98                  int res = in.read(buffer);
    99                  if (res == -1) {
    100                     break;
    101                 }
    102                 if (res > 0) {
    103                     total += res;
    104                     if (out != null) {
    105                         out.write(buffer, 0, res);
    106                     }
    107                 }
    108             }
    109             if (out != null) {
    110                 if (closeOutputStream) {
    111                     out.close();
    112                 } else {
    113                     out.flush();
    114                 }
    115                 out = null;
    116             }
    117             in.close();
    118             in = null;
    119             return total;
    120         } finally {
    121             IOUtils.closeQuietly(in);
    122             if (closeOutputStream) {
    123                 IOUtils.closeQuietly(out);
    124             }
    125         }
    126     }
    127
    128     /**
    129      * This convenience method allows to read a
    130      * {@link org.apache.commons.fileupload.FileItemStream}'s
    131      * content into a string. The platform's default character encoding
    132      * is used for converting bytes into characters.
    133      *
    134      * @param inputStream The input stream to read.
    135      * @see #asString(InputStream, String)
    136      * @return The streams contents, as a string.
    137      * @throws IOException An I/O error occurred.
    138      */
    139     public static String asString(InputStream inputStream) throws IOException {
    140         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    141         copy(inputStream, baos, true);
    142         return baos.toString();
    143     }
    144
    145     /**
    146      * This convenience method allows to read a
    147      * {@link org.apache.commons.fileupload.FileItemStream}'s
    148      * content into a string, using the given character encoding.
    149      *
    150      * @param inputStream The input stream to read.
    151      * @param encoding The character encoding, typically "UTF-8".
    152      * @see #asString(InputStream)
    153      * @return The streams contents, as a string.
    154      * @throws IOException An I/O error occurred.
    155      */
    156     public static String asString(InputStream inputStream, String encoding) throws IOException {
    157         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    158         copy(inputStream, baos, true);
    159         return baos.toString(encoding);
    160     }
    161
    162     /**
    163      * Checks, whether the given file name is valid in the sense,
    164      * that it doesn't contain any NUL characters. If the file name
    165      * is valid, it will be returned without any modifications. Otherwise,
    166      * an {@link InvalidFileNameException} is raised.
    167      *
    168      * @param fileName The file name to check
    169      * @return Unmodified file name, if valid.
    170      * @throws InvalidFileNameException The file name was found to be invalid.
    171      */
    172     public static String checkFileName(String fileName) {
    173         if (fileName != null  &&  fileName.indexOf('\u0000') != -1) {
    174             // pFileName.replace("\u0000", "\\0")
    175             final StringBuilder sb = new StringBuilder();
    176             for (int i = 0;  i < fileName.length();  i++) {
    177                 char c = fileName.charAt(i);
    178                 switch (c) {
    179                     case 0:
    180                         sb.append("\\0");
    181                         break;
    182                     default:
    183                         sb.append(c);
    184                         break;
    185                 }
    186             }
    187             throw new InvalidFileNameException(fileName,
    188                     "Invalid file name: " + sb);
    189         }
    190         return fileName;
    191     }
    192
    193 }