2 * This program is free software; you can redistribute it and/or modify it under
3 * the terms of the GNU General Public License as published by the Free Software
4 * Foundation; either version 2 of the License, or (at your option) any later
7 * This program is distributed in the hope that it will be useful, but WITHOUT
8 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12 * You should have received a copy of the GNU General Public License along with
13 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
14 * Place - Suite 330, Boston, MA 02111-1307, USA.
17 package de.todesbaum.util.io;
19 import java.io.EOFException;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.io.OutputStream;
23 import java.util.EventListener;
26 * Copies input from an {@link InputStream} to an {@link OutputStream}.
28 * @author <a href="mailto:droden@gmail.com">David Roden</a>
31 public class StreamCopier {
34 * The default size of the buffer.
36 private static final int BUFFER_SIZE = 64 * 1024;
39 * The {@link InputStream} to read from.
41 private InputStream inputStream;
44 * The {@link OutputStream} to write to.
46 private OutputStream outputStream;
49 * The number of bytes to copy.
54 * The size of the buffer.
56 private int bufferSize;
59 * Creates a new StreamCopier with the specified parameters and the default
63 * The {@link InputStream} to read from
65 * The {@link OutputStream} to write to
67 * The number of bytes to copy
69 public StreamCopier(InputStream inputStream, OutputStream outputStream, long length) {
70 this(inputStream, outputStream, length, BUFFER_SIZE);
74 * Creates a new StreamCopier with the specified parameters and the default
78 * The {@link InputStream} to read from
80 * The {@link OutputStream} to write to
82 * The number of bytes to copy
84 * The number of bytes to copy at a time
86 public StreamCopier(InputStream inputStream, OutputStream outputStream, long length, int bufferSize) {
87 this.inputStream = inputStream;
88 this.outputStream = outputStream;
90 this.bufferSize = bufferSize;
94 * Copies the stream data. If the input stream is depleted before the
95 * requested number of bytes have been read an {@link EOFException} is
98 * @throws EOFException
99 * if the input stream is depleted before the requested number
100 * of bytes has been read
101 * @throws IOException
102 * if an I/O error occurs
104 public void copy() throws EOFException, IOException {
105 copy(inputStream, outputStream, length, bufferSize);
109 * Copies the stream data. If the input stream is depleted before the
110 * requested number of bytes have been read an {@link EOFException} is
113 * @param progressListener
114 * The progress listener (may be {@code null})
115 * @throws EOFException
116 * if the input stream is depleted before the requested number
117 * of bytes has been read
118 * @throws IOException
119 * if an I/O error occurs
121 public void copy(ProgressListener progressListener) throws EOFException, IOException {
122 copy(inputStream, outputStream, length, bufferSize, progressListener);
126 * Copies <code>length</code> bytes from the <code>inputStream</code> to
127 * the <code>outputStream</code>.
130 * The input stream to read from
131 * @param outputStream
132 * The output stream to write to
134 * The number of bytes to copy
135 * @throws IOException
136 * if an I/O exception occurs
138 public static void copy(InputStream inputStream, OutputStream outputStream, long length) throws IOException {
139 copy(inputStream, outputStream, length, BUFFER_SIZE);
143 * Copies <code>length</code> bytes from the <code>inputStream</code> to
144 * the <code>outputStream</code>.
147 * The input stream to read from
148 * @param outputStream
149 * The output stream to write to
151 * The number of bytes to copy
152 * @param progressListener
153 * The progress listener (may be {@code null})
154 * @throws IOException
155 * if an I/O exception occurs
157 public static void copy(InputStream inputStream, OutputStream outputStream, long length, ProgressListener progressListener) throws IOException {
158 copy(inputStream, outputStream, length, BUFFER_SIZE, progressListener);
162 * Copies <code>length</code> bytes from the <code>inputStream</code> to
163 * the <code>outputStream</code> using a buffer with the specified size
166 * The input stream to read from
167 * @param outputStream
168 * The output stream to write to
170 * The number of bytes to copy
172 * The size of the copy buffer
173 * @throws IOException
174 * if an I/O exception occurs
176 public static void copy(InputStream inputStream, OutputStream outputStream, long length, int bufferSize) throws IOException {
177 copy(inputStream, outputStream, length, bufferSize, null);
181 * Copies <code>length</code> bytes from the <code>inputStream</code> to
182 * the <code>outputStream</code> using a buffer with the specified size
185 * The input stream to read from
186 * @param outputStream
187 * The output stream to write to
189 * The number of bytes to copy
191 * The size of the copy buffer
192 * @param progressListener
193 * The progress listener (may be {@code null})
194 * @throws IOException
195 * if an I/O exception occurs
197 public static void copy(InputStream inputStream, OutputStream outputStream, long length, int bufferSize, ProgressListener progressListener) throws IOException {
198 long remaining = length;
199 byte[] buffer = new byte[bufferSize];
200 while (remaining > 0) {
201 int read = inputStream.read(buffer, 0, (int) Math.min(Integer.MAX_VALUE, Math.min(bufferSize, remaining)));
203 throw new EOFException();
205 outputStream.write(buffer, 0, read);
207 if (progressListener != null) {
208 progressListener.onProgress(length - remaining, length);
214 * Interface for objects that want to be notified about the progress of a
215 * {@link StreamCopier#copy()} operation.
217 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
219 public static interface ProgressListener extends EventListener {
222 * Notifiies a listener that a copy process made some progress.
225 * The number of bytes that have already been copied
227 * The total number of bytes that will be copied
229 public void onProgress(long copied, long length);