2 * jSite - StreamCopier.java - Copyright © 2006–2012 David Roden
4 * This program is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License as published by the Free Software
6 * Foundation; either version 2 of the License, or (at your option) any later
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307, USA.
19 package de.todesbaum.util.io;
21 import java.io.EOFException;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.OutputStream;
25 import java.util.EventListener;
28 * Copies input from an {@link InputStream} to an {@link OutputStream}.
30 * @author <a href="mailto:droden@gmail.com">David Roden</a>
33 public class StreamCopier {
36 * The default size of the buffer.
38 private static final int BUFFER_SIZE = 64 * 1024;
41 * The {@link InputStream} to read from.
43 private InputStream inputStream;
46 * The {@link OutputStream} to write to.
48 private OutputStream outputStream;
51 * The number of bytes to copy.
56 * The size of the buffer.
58 private int bufferSize;
61 * Creates a new StreamCopier with the specified parameters and the default
65 * The {@link InputStream} to read from
67 * The {@link OutputStream} to write to
69 * The number of bytes to copy
71 public StreamCopier(InputStream inputStream, OutputStream outputStream, long length) {
72 this(inputStream, outputStream, length, BUFFER_SIZE);
76 * Creates a new StreamCopier with the specified parameters and the default
80 * The {@link InputStream} to read from
82 * The {@link OutputStream} to write to
84 * The number of bytes to copy
86 * The number of bytes to copy at a time
88 public StreamCopier(InputStream inputStream, OutputStream outputStream, long length, int bufferSize) {
89 this.inputStream = inputStream;
90 this.outputStream = outputStream;
92 this.bufferSize = bufferSize;
96 * Copies the stream data. If the input stream is depleted before the
97 * requested number of bytes have been read an {@link EOFException} is
100 * @throws EOFException
101 * if the input stream is depleted before the requested number
102 * of bytes has been read
103 * @throws IOException
104 * if an I/O error occurs
106 public void copy() throws EOFException, IOException {
107 copy(inputStream, outputStream, length, bufferSize);
111 * Copies the stream data. If the input stream is depleted before the
112 * requested number of bytes have been read an {@link EOFException} is
115 * @param progressListener
116 * The progress listener (may be {@code null})
117 * @throws EOFException
118 * if the input stream is depleted before the requested number
119 * of bytes has been read
120 * @throws IOException
121 * if an I/O error occurs
123 public void copy(ProgressListener progressListener) throws EOFException, IOException {
124 copy(inputStream, outputStream, length, bufferSize, progressListener);
128 * Copies <code>length</code> bytes from the <code>inputStream</code> to
129 * the <code>outputStream</code>.
132 * The input stream to read from
133 * @param outputStream
134 * The output stream to write to
136 * The number of bytes to copy
137 * @throws IOException
138 * if an I/O exception occurs
140 public static void copy(InputStream inputStream, OutputStream outputStream, long length) throws IOException {
141 copy(inputStream, outputStream, length, BUFFER_SIZE);
145 * Copies <code>length</code> bytes from the <code>inputStream</code> to
146 * the <code>outputStream</code>.
149 * The input stream to read from
150 * @param outputStream
151 * The output stream to write to
153 * The number of bytes to copy
154 * @param progressListener
155 * The progress listener (may be {@code null})
156 * @throws IOException
157 * if an I/O exception occurs
159 public static void copy(InputStream inputStream, OutputStream outputStream, long length, ProgressListener progressListener) throws IOException {
160 copy(inputStream, outputStream, length, BUFFER_SIZE, progressListener);
164 * Copies <code>length</code> bytes from the <code>inputStream</code> to
165 * the <code>outputStream</code> using a buffer with the specified size
168 * The input stream to read from
169 * @param outputStream
170 * The output stream to write to
172 * The number of bytes to copy
174 * The size of the copy buffer
175 * @throws IOException
176 * if an I/O exception occurs
178 public static void copy(InputStream inputStream, OutputStream outputStream, long length, int bufferSize) throws IOException {
179 copy(inputStream, outputStream, length, bufferSize, null);
183 * Copies <code>length</code> bytes from the <code>inputStream</code> to
184 * the <code>outputStream</code> using a buffer with the specified size
187 * The input stream to read from
188 * @param outputStream
189 * The output stream to write to
191 * The number of bytes to copy
193 * The size of the copy buffer
194 * @param progressListener
195 * The progress listener (may be {@code null})
196 * @throws IOException
197 * if an I/O exception occurs
199 public static void copy(InputStream inputStream, OutputStream outputStream, long length, int bufferSize, ProgressListener progressListener) throws IOException {
200 long remaining = length;
201 byte[] buffer = new byte[bufferSize];
202 while (remaining > 0) {
203 int read = inputStream.read(buffer, 0, (int) Math.min(Integer.MAX_VALUE, Math.min(bufferSize, remaining)));
205 throw new EOFException();
207 outputStream.write(buffer, 0, read);
209 if (progressListener != null) {
210 progressListener.onProgress(length - remaining, length);
216 * Interface for objects that want to be notified about the progress of a
217 * {@link StreamCopier#copy()} operation.
219 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
221 public static interface ProgressListener extends EventListener {
224 * Notifiies a listener that a copy process made some progress.
227 * The number of bytes that have already been copied
229 * The total number of bytes that will be copied
231 public void onProgress(long copied, long length);