001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.fileupload.util;
018
019 import java.io.ByteArrayOutputStream;
020 import java.io.IOException;
021 import java.io.InputStream;
022 import java.io.OutputStream;
023
024
025 /** Utility class for working with streams.
026 */
027 public final class Streams {
028 /**
029 * Private constructor, to prevent instantiation.
030 * This class has only static methods.
031 */
032 private Streams() {
033 // Does nothing
034 }
035
036 /**
037 * Default buffer size for use in
038 * {@link #copy(InputStream, OutputStream, boolean)}.
039 */
040 private static final int DEFAULT_BUFFER_SIZE = 8192;
041
042 /**
043 * Copies the contents of the given {@link InputStream}
044 * to the given {@link OutputStream}. Shortcut for
045 * <pre>
046 * copy(pInputStream, pOutputStream, new byte[8192]);
047 * </pre>
048 * @param pInputStream The input stream, which is being read.
049 * It is guaranteed, that {@link InputStream#close()} is called
050 * on the stream.
051 * @param pOutputStream The output stream, to which data should
052 * be written. May be null, in which case the input streams
053 * contents are simply discarded.
054 * @param pClose True guarantees, that {@link OutputStream#close()}
055 * is called on the stream. False indicates, that only
056 * {@link OutputStream#flush()} should be called finally.
057 *
058 * @return Number of bytes, which have been copied.
059 * @throws IOException An I/O error occurred.
060 */
061 public static long copy(InputStream pInputStream,
062 OutputStream pOutputStream, boolean pClose)
063 throws IOException {
064 return copy(pInputStream, pOutputStream, pClose,
065 new byte[DEFAULT_BUFFER_SIZE]);
066 }
067
068 /**
069 * Copies the contents of the given {@link InputStream}
070 * to the given {@link OutputStream}.
071 * @param pIn The input stream, which is being read.
072 * It is guaranteed, that {@link InputStream#close()} is called
073 * on the stream.
074 * @param pOut The output stream, to which data should
075 * be written. May be null, in which case the input streams
076 * contents are simply discarded.
077 * @param pClose True guarantees, that {@link OutputStream#close()}
078 * is called on the stream. False indicates, that only
079 * {@link OutputStream#flush()} should be called finally.
080 * @param pBuffer Temporary buffer, which is to be used for
081 * copying data.
082 * @return Number of bytes, which have been copied.
083 * @throws IOException An I/O error occurred.
084 */
085 public static long copy(InputStream pIn,
086 OutputStream pOut, boolean pClose,
087 byte[] pBuffer)
088 throws IOException {
089 OutputStream out = pOut;
090 InputStream in = pIn;
091 try {
092 long total = 0;
093 for (;;) {
094 int res = in.read(pBuffer);
095 if (res == -1) {
096 break;
097 }
098 if (res > 0) {
099 total += res;
100 if (out != null) {
101 out.write(pBuffer, 0, res);
102 }
103 }
104 }
105 if (out != null) {
106 if (pClose) {
107 out.close();
108 } else {
109 out.flush();
110 }
111 out = null;
112 }
113 in.close();
114 in = null;
115 return total;
116 } finally {
117 if (in != null) {
118 try {
119 in.close();
120 } catch (Throwable t) {
121 /* Ignore me */
122 }
123 }
124 if (pClose && out != null) {
125 try {
126 out.close();
127 } catch (Throwable t) {
128 /* Ignore me */
129 }
130 }
131 }
132 }
133
134 /**
135 * This convenience method allows to read a
136 * {@link org.apache.commons.fileupload.FileItemStream}'s
137 * content into a string. The platform's default character encoding
138 * is used for converting bytes into characters.
139 * @param pStream The input stream to read.
140 * @see #asString(InputStream, String)
141 * @return The streams contents, as a string.
142 * @throws IOException An I/O error occurred.
143 */
144 public static String asString(InputStream pStream) throws IOException {
145 ByteArrayOutputStream baos = new ByteArrayOutputStream();
146 copy(pStream, baos, true);
147 return baos.toString();
148 }
149
150 /**
151 * This convenience method allows to read a
152 * {@link org.apache.commons.fileupload.FileItemStream}'s
153 * content into a string, using the given character encoding.
154 * @param pStream The input stream to read.
155 * @param pEncoding The character encoding, typically "UTF-8".
156 * @see #asString(InputStream)
157 * @return The streams contents, as a string.
158 * @throws IOException An I/O error occurred.
159 */
160 public static String asString(InputStream pStream, String pEncoding)
161 throws IOException {
162 ByteArrayOutputStream baos = new ByteArrayOutputStream();
163 copy(pStream, baos, true);
164 return baos.toString(pEncoding);
165 }
166 }