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.camel.util;
018    
019    import java.io.IOException;
020    import java.io.InputStream;
021    import java.io.OutputStream;
022    import java.io.UnsupportedEncodingException;
023    import java.nio.charset.Charset;
024    
025    /**
026     * IO helper class.
027     *
028     * @version $Revision: 769303 $
029     */
030    public final class IOHelper {
031        
032        private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
033        private static final Charset UTF8_CHARSET = Charset.forName("utf-8");
034    
035        private IOHelper() {
036            //Utility Class
037        }
038        
039        /**
040         * Use this function instead of new String(byte[]) to avoid surprises from non-standard default encodings.
041         */
042        public static String newStringFromBytes(byte[] bytes) {
043            try {
044                return new String(bytes, UTF8_CHARSET.name());
045            } catch (UnsupportedEncodingException e) {
046                throw new RuntimeException("Impossible failure: Charset.forName(\"utf-8\") returns invalid name.", e);
047            }
048        }
049    
050        /**
051         * Use this function instead of new String(byte[], int, int) 
052         * to avoid surprises from non-standard default encodings.
053         */
054        public static String newStringFromBytes(byte[] bytes, int start, int length) {
055            try {
056                return new String(bytes, start, length, UTF8_CHARSET.name());
057            } catch (UnsupportedEncodingException e) {
058                throw new RuntimeException("Impossible failure: Charset.forName(\"utf-8\") returns invalid name.", e);
059            }
060        }
061    
062        /**
063         * A factory method which creates an {@link IOException} from the given
064         * exception and message
065         */
066        public static IOException createIOException(Throwable cause) {
067            return createIOException(cause.getMessage(), cause);
068        }
069    
070        /**
071         * A factory method which creates an {@link IOException} from the given
072         * exception and message
073         */
074        public static IOException createIOException(String message, Throwable cause) {
075            IOException answer = new IOException(message);
076            answer.initCause(cause);
077            return answer;
078        }
079    
080        public static int copy(InputStream input, OutputStream output) throws IOException {
081            return copy(input, output, DEFAULT_BUFFER_SIZE);
082        }
083        
084        public static int copy(final InputStream input, final OutputStream output, int bufferSize)
085            throws IOException {
086            int avail = input.available();
087            if (avail > 262144) {
088                avail = 262144;
089            }
090            if (avail > bufferSize) {
091                bufferSize = avail;
092            }
093            final byte[] buffer = new byte[bufferSize];
094            int n = 0;
095            n = input.read(buffer);
096            int total = 0;
097            while (-1 != n) {
098                output.write(buffer, 0, n);
099                total += n;
100                n = input.read(buffer);
101            }
102            output.flush();
103            return total;
104        }
105        
106        public static void copyAndCloseInput(InputStream input, OutputStream output) throws IOException {
107            copy(input, output);
108            input.close();
109        }
110        
111        public static void copyAndCloseInput(InputStream input, OutputStream output, int bufferSize) throws IOException {
112            copy(input, output, bufferSize);
113        }
114    }