1bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/*
2bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Licensed to the Apache Software Foundation (ASF) under one or more
3bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * contributor license agreements.  See the NOTICE file distributed with
4bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * this work for additional information regarding copyright ownership.
5bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The ASF licenses this file to You under the Apache License, Version 2.0
6bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * (the "License"); you may not use this file except in compliance with
7bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * the License.  You may obtain a copy of the License at
8bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
9bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *      http://www.apache.org/licenses/LICENSE-2.0
10bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
11bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Unless required by applicable law or agreed to in writing, software
12bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * distributed under the License is distributed on an "AS IS" BASIS,
13bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * See the License for the specific language governing permissions and
15bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * limitations under the License.
16bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */
17bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpackage org.apache.commons.io;
18bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
19bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.ByteArrayInputStream;
20bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.IOException;
21bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.InputStream;
22bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.InputStreamReader;
23bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.OutputStream;
24bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.OutputStreamWriter;
25bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.Reader;
26bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.StringReader;
27bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookimport java.io.Writer;
28bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
29bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook/**
30bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * This class provides static utility methods for buffered
31bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * copying between sources (<code>InputStream</code>, <code>Reader</code>,
32bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>String</code> and <code>byte[]</code>) and destinations
33bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * (<code>OutputStream</code>, <code>Writer</code>, <code>String</code> and
34bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>byte[]</code>).
35bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>
36bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Unless otherwise noted, these <code>copy</code> methods do <em>not</em>
37bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * flush or close the streams. Often doing so would require making non-portable
38bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * assumptions about the streams' origin and further use. This means that both
39bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * streams' <code>close()</code> methods must be called after copying. if one
40bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * omits this step, then the stream resources (sockets, file descriptors) are
41bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * released when the associated Stream is garbage-collected. It is not a good
42bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * idea to rely on this mechanism. For a good overview of the distinction
43bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * between "memory management" and "resource management", see
44bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <a href="http://www.unixreview.com/articles/1998/9804/9804ja/ja.htm">this
45bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * UnixReview article</a>.
46bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>
47bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * For byte-to-char methods, a <code>copy</code> variant allows the encoding
48bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * to be selected (otherwise the platform default is used). We would like to
49bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * encourage you to always specify the encoding because relying on the platform
50bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * default can lead to unexpected results.
51bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p
52bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * We don't provide special variants for the <code>copy</code> methods that
53bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * let you specify the buffer size because in modern VMs the impact on speed
54bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * seems to be minimal. We're using a default buffer size of 4 KB.
55bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>
56bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The <code>copy</code> methods use an internal buffer when copying. It is
57bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * therefore advisable <em>not</em> to deliberately wrap the stream arguments
58bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * to the <code>copy</code> methods in <code>Buffered*</code> streams. For
59bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * example, don't do the following:
60bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <pre>
61bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *  copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) );
62bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *  </pre>
63bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * The rationale is as follows:
64bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>
65bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Imagine that an InputStream's read() is a very expensive operation, which
66bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * would usually suggest wrapping in a BufferedInputStream. The
67bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * BufferedInputStream works by issuing infrequent
68bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the
69bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * underlying InputStream, to fill an internal buffer, from which further
70bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <code>read</code> requests can inexpensively get their data (until the buffer
71bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * runs out).
72bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>
73bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * However, the <code>copy</code> methods do the same thing, keeping an
74bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * internal buffer, populated by
75bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * {@link InputStream#read(byte[] b, int off, int len)} requests. Having two
76bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * buffers (or three if the destination stream is also buffered) is pointless,
77bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * and the unnecessary buffer management hurts performance slightly (about 3%,
78bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * according to some simple experiments).
79bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>
80bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Behold, intrepid explorers; a map of this class:
81bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <pre>
82bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *       Method      Input               Output          Dependency
83bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *       ------      -----               ------          -------
84bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 1     copy        InputStream         OutputStream    (primitive)
85bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 2     copy        Reader              Writer          (primitive)
86bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
87bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 3     copy        InputStream         Writer          2
88bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
89bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 4     copy        Reader              OutputStream    2
90bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
91bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 5     copy        String              OutputStream    2
92bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 6     copy        String              Writer          (trivial)
93bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
94bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 7     copy        byte[]              Writer          3
95bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * 8     copy        byte[]              OutputStream    (trivial)
96bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * </pre>
97bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>
98bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Note that only the first two methods shuffle bytes; the rest use these
99bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * two, or (if possible) copy using native Java copy methods. As there are
100bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * method variants to specify the encoding, each row may
101bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * correspond to up to 2 methods.
102bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * <p>
103bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * Origin of code: Excalibur.
104bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *
105bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @author Peter Donald
106bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @author Jeff Turner
107bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @author Matthew Hawthorne
108bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @version $Id: CopyUtils.java 437680 2006-08-28 11:57:00Z scolebourne $
109bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook * @deprecated Use IOUtils. Will be removed in 2.0.
110bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *  Methods renamed to IOUtils.write() or IOUtils.copy().
111bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *  Null handling behaviour changed in IOUtils (null data does not
112bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook *  throw NullPointerException).
113bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook */
114bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrookpublic class CopyUtils {
115bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
116bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
117bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * The default size of the buffer.
118bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
119bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
120bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
121bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
122bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Instances should NOT be constructed in standard programming.
123bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
124bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public CopyUtils() { }
125bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
126bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
127bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // byte[] -> OutputStream
128bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
129bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
130bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
131bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
132bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param input the byte array to read from
133bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param output the <code>OutputStream</code> to write to
134bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException In case of an I/O problem
135bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
136bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static void copy(byte[] input, OutputStream output)
137bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            throws IOException {
138bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        output.write(input);
139bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
140bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
141bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
142bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // byte[] -> Writer
143bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
144bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
145bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
146bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Copy and convert bytes from a <code>byte[]</code> to chars on a
147bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>Writer</code>.
148bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * The platform's default encoding is used for the byte-to-char conversion.
149bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param input the byte array to read from
150bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param output the <code>Writer</code> to write to
151bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException In case of an I/O problem
152bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
153bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static void copy(byte[] input, Writer output)
154bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            throws IOException {
155bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        ByteArrayInputStream in = new ByteArrayInputStream(input);
156bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        copy(in, output);
157bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
158bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
159bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
160bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
161bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Copy and convert bytes from a <code>byte[]</code> to chars on a
162bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>Writer</code>, using the specified encoding.
163bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param input the byte array to read from
164bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param output the <code>Writer</code> to write to
165bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param encoding The name of a supported character encoding. See the
166bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <a href="http://www.iana.org/assignments/character-sets">IANA
167bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Charset Registry</a> for a list of valid encoding types.
168bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException In case of an I/O problem
169bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
170bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static void copy(
171bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            byte[] input,
172bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            Writer output,
173bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            String encoding)
174bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                throws IOException {
175bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        ByteArrayInputStream in = new ByteArrayInputStream(input);
176bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        copy(in, output, encoding);
177bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
178bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
179bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
180bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
181bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // Core copy methods
182bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
183bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
184bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
185bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Copy bytes from an <code>InputStream</code> to an
186bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>OutputStream</code>.
187bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param input the <code>InputStream</code> to read from
188bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param output the <code>OutputStream</code> to write to
189bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return the number of bytes copied
190bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException In case of an I/O problem
191bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
192bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static int copy(
193bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            InputStream input,
194bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            OutputStream output)
195bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                throws IOException {
196bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
197bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        int count = 0;
198bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        int n = 0;
199bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        while (-1 != (n = input.read(buffer))) {
200bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            output.write(buffer, 0, n);
201bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            count += n;
202bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
203bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return count;
204bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
205bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
206bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
207bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // Reader -> Writer
208bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
209bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
210bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
211bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
212bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param input the <code>Reader</code> to read from
213bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param output the <code>Writer</code> to write to
214bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @return the number of characters copied
215bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException In case of an I/O problem
216bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
217bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static int copy(
218bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            Reader input,
219bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            Writer output)
220bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                throws IOException {
221bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        char[] buffer = new char[DEFAULT_BUFFER_SIZE];
222bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        int count = 0;
223bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        int n = 0;
224bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        while (-1 != (n = input.read(buffer))) {
225bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            output.write(buffer, 0, n);
226bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            count += n;
227bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        }
228bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        return count;
229bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
230bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
231bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
232bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // InputStream -> Writer
233bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
234bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
235bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
236bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Copy and convert bytes from an <code>InputStream</code> to chars on a
237bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>Writer</code>.
238bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * The platform's default encoding is used for the byte-to-char conversion.
239bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param input the <code>InputStream</code> to read from
240bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param output the <code>Writer</code> to write to
241bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException In case of an I/O problem
242bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
243bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static void copy(
244bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            InputStream input,
245bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            Writer output)
246bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                throws IOException {
247bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        InputStreamReader in = new InputStreamReader(input);
248bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        copy(in, output);
249bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
250bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
251bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
252bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Copy and convert bytes from an <code>InputStream</code> to chars on a
253bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>Writer</code>, using the specified encoding.
254bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param input the <code>InputStream</code> to read from
255bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param output the <code>Writer</code> to write to
256bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param encoding The name of a supported character encoding. See the
257bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <a href="http://www.iana.org/assignments/character-sets">IANA
258bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Charset Registry</a> for a list of valid encoding types.
259bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException In case of an I/O problem
260bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
261bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static void copy(
262bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            InputStream input,
263bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            Writer output,
264bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            String encoding)
265bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                throws IOException {
266bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        InputStreamReader in = new InputStreamReader(input, encoding);
267bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        copy(in, output);
268bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
269bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
270bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
271bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
272bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // Reader -> OutputStream
273bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
274bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
275bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
276bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Serialize chars from a <code>Reader</code> to bytes on an
277bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>OutputStream</code>, and flush the <code>OutputStream</code>.
278bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param input the <code>Reader</code> to read from
279bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param output the <code>OutputStream</code> to write to
280bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException In case of an I/O problem
281bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
282bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static void copy(
283bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            Reader input,
284bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            OutputStream output)
285bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                throws IOException {
286bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        OutputStreamWriter out = new OutputStreamWriter(output);
287bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        copy(input, out);
288bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
289bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // have to flush here.
290bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        out.flush();
291bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
292bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
293bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
294bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // String -> OutputStream
295bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
296bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
297bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
298bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Serialize chars from a <code>String</code> to bytes on an
299bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * <code>OutputStream</code>, and
300bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * flush the <code>OutputStream</code>.
301bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param input the <code>String</code> to read from
302bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param output the <code>OutputStream</code> to write to
303bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException In case of an I/O problem
304bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
305bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static void copy(
306bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            String input,
307bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook            OutputStream output)
308bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                throws IOException {
309bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        StringReader in = new StringReader(input);
310bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        OutputStreamWriter out = new OutputStreamWriter(output);
311bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        copy(in, out);
312bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // XXX Unless anyone is planning on rewriting OutputStreamWriter, we
313bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        // have to flush here.
314bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        out.flush();
315bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
316bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
317bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
318bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // String -> Writer
319bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    // ----------------------------------------------------------------
320bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
321bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    /**
322bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * Copy chars from a <code>String</code> to a <code>Writer</code>.
323bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param input the <code>String</code> to read from
324bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @param output the <code>Writer</code> to write to
325bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     * @throws IOException In case of an I/O problem
326bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook     */
327bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    public static void copy(String input, Writer output)
328bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook                throws IOException {
329bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook        output.write(input);
330bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook    }
331bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook
332bc47398187c6ffd132435e51d8d61e6ec79a79dbPaul Westbrook}
333