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    }