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
    26
    27  /** Utility class for working with streams.
    28   */
    29  public final class Streams {
    30      /**
    31       * Private constructor, to prevent instantiation.
    32       * This class has only static methods.
    33       */
    34      private Streams() {
    35          // Does nothing
    36      }
    37
    38      /**
    39       * Default buffer size for use in
    40       * {@link #copy(InputStream, OutputStream, boolean)}.
    41       */
    42      private static final int DEFAULT_BUFFER_SIZE = 8192;
    43
    44      /**
    45       * Copies the contents of the given {@link InputStream}
    46       * to the given {@link OutputStream}. Shortcut for
    47       * <pre>
    48       *   copy(pInputStream, pOutputStream, new byte[8192]);
    49       * </pre>
    50       * @param pInputStream The input stream, which is being read.
    51       * It is guaranteed, that {@link InputStream#close()} is called
    52       * on the stream.
    53       * @param pOutputStream The output stream, to which data should
    54       * be written. May be null, in which case the input streams
    55       * contents are simply discarded.
    56       * @param pClose True guarantees, that {@link OutputStream#close()}
    57       * is called on the stream. False indicates, that only
    58       * {@link OutputStream#flush()} should be called finally.
    59       *
    60       * @return Number of bytes, which have been copied.
    61       * @throws IOException An I/O error occurred.
    62       */
    63      public static long copy(InputStream pInputStream,
    64              OutputStream pOutputStream, boolean pClose)
    65              throws IOException {
    66          return copy(pInputStream, pOutputStream, pClose,
    67                  new byte[DEFAULT_BUFFER_SIZE]);
    68      }
    69
    70      /**
    71       * Copies the contents of the given {@link InputStream}
    72       * to the given {@link OutputStream}.
    73       * @param pIn The input stream, which is being read.
    74       *   It is guaranteed, that {@link InputStream#close()} is called
    75       *   on the stream.
    76       * @param pOut The output stream, to which data should
    77       *   be written. May be null, in which case the input streams
    78       *   contents are simply discarded.
    79       * @param pClose True guarantees, that {@link OutputStream#close()}
    80       *   is called on the stream. False indicates, that only
    81       *   {@link OutputStream#flush()} should be called finally.
    82       * @param pBuffer Temporary buffer, which is to be used for
    83       *   copying data.
    84       * @return Number of bytes, which have been copied.
    85       * @throws IOException An I/O error occurred.
    86       */
    87      public static long copy(InputStream pIn,
    88              OutputStream pOut, boolean pClose,
    89              byte[] pBuffer)
    90      throws IOException {
    91          OutputStream out = pOut;
    92          InputStream in = pIn;
    93          try {
    94              long total = 0;
    95              for (;;) {
    96                  int res = in.read(pBuffer);
    97                  if (res == -1) {
    98                      break;
    99                  }
    100                 if (res > 0) {
    101                     total += res;
    102                     if (out != null) {
    103                         out.write(pBuffer, 0, res);
    104                     }
    105                 }
    106             }
    107             if (out != null) {
    108                 if (pClose) {
    109                     out.close();
    110                 } else {
    111                     out.flush();
    112                 }
    113                 out = null;
    114             }
    115             in.close();
    116             in = null;
    117             return total;
    118         } finally {
    119             if (in != null) {
    120                 try {
    121                     in.close();
    122                 } catch (Throwable t) {
    123                     /* Ignore me */
    124                 }
    125             }
    126             if (pClose  &&  out != null) {
    127                 try {
    128                     out.close();
    129                 } catch (Throwable t) {
    130                     /* Ignore me */
    131                 }
    132             }
    133         }
    134     }
    135
    136     /**
    137      * This convenience method allows to read a
    138      * {@link org.apache.commons.fileupload.FileItemStream}'s
    139      * content into a string. The platform's default character encoding
    140      * is used for converting bytes into characters.
    141      * @param pStream The input stream to read.
    142      * @see #asString(InputStream, String)
    143      * @return The streams contents, as a string.
    144      * @throws IOException An I/O error occurred.
    145      */
    146     public static String asString(InputStream pStream) throws IOException {
    147         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    148         copy(pStream, baos, true);
    149         return baos.toString();
    150     }
    151
    152     /**
    153      * This convenience method allows to read a
    154      * {@link org.apache.commons.fileupload.FileItemStream}'s
    155      * content into a string, using the given character encoding.
    156      * @param pStream The input stream to read.
    157      * @param pEncoding The character encoding, typically "UTF-8".
    158      * @see #asString(InputStream)
    159      * @return The streams contents, as a string.
    160      * @throws IOException An I/O error occurred.
    161      */
    162     public static String asString(InputStream pStream, String pEncoding)
    163             throws IOException {
    164         ByteArrayOutputStream baos = new ByteArrayOutputStream();
    165         copy(pStream, baos, true);
    166         return baos.toString(pEncoding);
    167     }
    168
    169     /**
    170      * Checks, whether the given file name is valid in the sense,
    171      * that it doesn't contain any NUL characters. If the file name
    172      * is valid, it will be returned without any modifications. Otherwise,
    173      * an {@link InvalidFileNameException} is raised.
    174      * @param pFileName The file name to check
    175      * @return Unmodified file name, if valid.
    176      * @throws InvalidFileNameException The file name was found to be invalid.
    177      */
    178     public static String checkFileName(String pFileName) {
    179         if (pFileName != null  &&  pFileName.indexOf('\u0000') != -1) {
    180             // pFileName.replace("\u0000", "\\0")
    181             final StringBuffer sb = new StringBuffer();
    182             for (int i = 0;  i < pFileName.length();  i++) {
    183                 char c = pFileName.charAt(i);
    184                 switch (c) {
    185                     case 0:
    186                         sb.append("\\0");
    187                         break;
    188                     default:
    189                         sb.append(c);
    190                         break;
    191                 }
    192             }
    193             throw new InvalidFileNameException(pFileName,
    194                     "Invalid file name: " + sb);
    195         }
    196         return pFileName;
    197     }
    198 }