2
* Copyright 2001-2004 The Apache Software Foundation.
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
16
package org.apache.commons.io;
18
import java.io.ByteArrayInputStream;
19
import java.io.IOException;
20
import java.io.InputStream;
21
import java.io.InputStreamReader;
22
import java.io.OutputStream;
23
import java.io.OutputStreamWriter;
24
import java.io.Reader;
25
import java.io.StringReader;
26
import java.io.Writer;
30
* This class provides static utility methods for buffered
31
* copying between sources (<code>InputStream</code>, <code>Reader</code>, <code>String</code> and
32
* <code>byte[]</code>) and destinations (<code>OutputStream</code>, <code>Writer</code>,
33
* <code>String</code> and <code>byte[]</code>).
36
* <p>Unless otherwise noted, these <code>copy</code> methods do <em>not</em> flush or close the
37
* streams. Often doing so would require making non-portable assumptions about the streams' origin
38
* and further use. This means that both streams' <code>close()</code> methods must be called after
39
* copying. if one omits this step, then the stream resources (sockets, file descriptors) are
40
* released when the associated Stream is garbage-collected. It is not a good idea to rely on this
41
* mechanism. For a good overview of the distinction between "memory management" and "resource
42
* management", see <a href="http://www.unixreview.com/articles/1998/9804/9804ja/ja.htm">this
43
* UnixReview article</a>.</p>
45
* <p>For byte-to-char methods, a <code>copy</code> variant allows the encoding
46
* to be selected (otherwise the platform default is used). We would like to
47
* encourage you to always specify the encoding because relying on the platform
48
* default can lead to unexpected results.</p>
50
* <p>We don't provide special variants for the <code>copy</code> methods that
51
* let you specify the buffer size because in modern VMs the impact on speed
52
* seems to be minimal. We're using a default buffer size of 4 KB.</p>
54
* <p>The <code>copy</code> methods use an internal buffer when copying. It is therefore advisable
55
* <em>not</em> to deliberately wrap the stream arguments to the <code>copy</code> methods in
56
* <code>Buffered*</code> streams. For example, don't do the
59
* <code>copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) );</code>
61
* <p>The rationale is as follows:</p>
63
* <p>Imagine that an InputStream's read() is a very expensive operation, which would usually suggest
64
* wrapping in a BufferedInputStream. The BufferedInputStream works by issuing infrequent
65
* {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the underlying InputStream, to
66
* fill an internal buffer, from which further <code>read</code> requests can inexpensively get
67
* their data (until the buffer runs out).</p>
68
* <p>However, the <code>copy</code> methods do the same thing, keeping an internal buffer,
69
* populated by {@link InputStream#read(byte[] b, int off, int len)} requests. Having two buffers
70
* (or three if the destination stream is also buffered) is pointless, and the unnecessary buffer
71
* management hurts performance slightly (about 3%, according to some simple experiments).</p>
73
* <p>Behold, intrepid explorers; a map of this class:</p>
75
* Method Input Output Dependency
76
* ------ ----- ------ -------
77
* 1 copy InputStream OutputStream (primitive)
78
* 2 copy Reader Writer (primitive)
80
* 3 copy InputStream Writer 2
82
* 4 copy Reader OutputStream 2
84
* 5 copy String OutputStream 2
85
* 6 copy String Writer (trivial)
87
* 7 copy byte[] Writer 3
88
* 8 copy byte[] OutputStream (trivial)
91
* <p>Note that only the first two methods shuffle bytes; the rest use these
92
* two, or (if possible) copy using native Java copy methods. As there are
93
* method variants to specify the encoding, each row may
94
* correspond to up to 2 methods.</p>
96
* <p>Origin of code: Apache Avalon (Excalibur)</p>
98
* @author Peter Donald
100
* @author Matthew Hawthorne
101
* @version $Id: CopyUtils.java,v 1.6 2004/04/24 23:49:25 bayard Exp $
103
public class CopyUtils {
106
* The name says it all.
108
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
111
* Instances should NOT be constructed in standard programming.
113
public CopyUtils() {}
115
// ----------------------------------------------------------------
116
// byte[] -> OutputStream
117
// ----------------------------------------------------------------
120
* Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
121
* @param input the byte array to read from
122
* @param output the <code>OutputStream</code> to write to
123
* @throws IOException In case of an I/O problem
125
public static void copy(byte[] input, OutputStream output)
130
// ----------------------------------------------------------------
132
// ----------------------------------------------------------------
135
* Copy and convert bytes from a <code>byte[]</code> to chars on a
136
* <code>Writer</code>.
137
* The platform's default encoding is used for the byte-to-char conversion.
138
* @param input the byte array to read from
139
* @param output the <code>Writer</code> to write to
140
* @throws IOException In case of an I/O problem
142
public static void copy(byte[] input, Writer output)
144
ByteArrayInputStream in = new ByteArrayInputStream(input);
150
* Copy and convert bytes from a <code>byte[]</code> to chars on a
151
* <code>Writer</code>, using the specified encoding.
152
* @param input the byte array to read from
153
* @param output the <code>Writer</code> to write to
154
* @param encoding The name of a supported character encoding. See the
155
* <a href="http://www.iana.org/assignments/character-sets">IANA
156
* Charset Registry</a> for a list of valid encoding types.
157
* @throws IOException In case of an I/O problem
159
public static void copy(
164
ByteArrayInputStream in = new ByteArrayInputStream(input);
165
copy(in, output, encoding);
169
// ----------------------------------------------------------------
171
// ----------------------------------------------------------------
174
* Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
175
* @param input the <code>InputStream</code> to read from
176
* @param output the <code>OutputStream</code> to write to
177
* @return the number of bytes copied
178
* @throws IOException In case of an I/O problem
180
public static int copy(
184
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
187
while (-1 != (n = input.read(buffer))) {
188
output.write(buffer, 0, n);
194
// ----------------------------------------------------------------
196
// ----------------------------------------------------------------
199
* Copy chars from a <code>Reader</code> to a <code>Writer</code>.
200
* @param input the <code>Reader</code> to read from
201
* @param output the <code>Writer</code> to write to
202
* @return the number of characters copied
203
* @throws IOException In case of an I/O problem
205
public static int copy(
209
char[] buffer = new char[DEFAULT_BUFFER_SIZE];
212
while (-1 != (n = input.read(buffer))) {
213
output.write(buffer, 0, n);
219
// ----------------------------------------------------------------
220
// InputStream -> Writer
221
// ----------------------------------------------------------------
224
* Copy and convert bytes from an <code>InputStream</code> to chars on a
225
* <code>Writer</code>.
226
* The platform's default encoding is used for the byte-to-char conversion.
227
* @param input the <code>InputStream</code> to read from
228
* @param output the <code>Writer</code> to write to
229
* @throws IOException In case of an I/O problem
231
public static void copy(
235
InputStreamReader in = new InputStreamReader(input);
240
* Copy and convert bytes from an <code>InputStream</code> to chars on a
241
* <code>Writer</code>, using the specified encoding.
242
* @param input the <code>InputStream</code> to read from
243
* @param output the <code>Writer</code> to write to
244
* @param encoding The name of a supported character encoding. See the
245
* <a href="http://www.iana.org/assignments/character-sets">IANA
246
* Charset Registry</a> for a list of valid encoding types.
247
* @throws IOException In case of an I/O problem
249
public static void copy(
254
InputStreamReader in = new InputStreamReader(input, encoding);
259
// ----------------------------------------------------------------
260
// Reader -> OutputStream
261
// ----------------------------------------------------------------
264
* Serialize chars from a <code>Reader</code> to bytes on an
265
* <code>OutputStream</code>, and flush the <code>OutputStream</code>.
266
* @param input the <code>Reader</code> to read from
267
* @param output the <code>OutputStream</code> to write to
268
* @throws IOException In case of an I/O problem
270
public static void copy(
274
OutputStreamWriter out = new OutputStreamWriter(output);
276
// XXX Unless anyone is planning on rewriting OutputStreamWriter, we have to flush here.
280
// ----------------------------------------------------------------
281
// String -> OutputStream
282
// ----------------------------------------------------------------
285
* Serialize chars from a <code>String</code> to bytes on an <code>OutputStream</code>, and
286
* flush the <code>OutputStream</code>.
287
* @param input the <code>String</code> to read from
288
* @param output the <code>OutputStream</code> to write to
289
* @throws IOException In case of an I/O problem
291
public static void copy(
295
StringReader in = new StringReader(input);
296
OutputStreamWriter out = new OutputStreamWriter(output);
298
// XXX Unless anyone is planning on rewriting OutputStreamWriter, we have to flush here.
302
// ----------------------------------------------------------------
304
// ----------------------------------------------------------------
307
* Copy chars from a <code>String</code> to a <code>Writer</code>.
308
* @param input the <code>String</code> to read from
309
* @param output the <code>Writer</code> to write to
310
* @throws IOException In case of an I/O problem
312
public static void copy(String input, Writer output)