|
32 | 32 | */
|
33 | 33 | public abstract class Streams {
|
34 | 34 |
|
| 35 | + private static final ThreadLocal<byte[]> buffer = ThreadLocal.withInitial(() -> new byte[8 * 1024]); |
| 36 | + |
35 | 37 | /**
|
36 |
| - * Copy the contents of the given InputStream to the given OutputStream. |
37 |
| - * Closes both streams when done. |
| 38 | + * Copy the contents of the given InputStream to the given OutputStream. Optionally, closes both streams when done. |
38 | 39 | *
|
39 |
| - * @param in the stream to copy from |
40 |
| - * @param out the stream to copy to |
| 40 | + * @param in the stream to copy from |
| 41 | + * @param out the stream to copy to |
| 42 | + * @param close whether to close both streams after copying |
| 43 | + * @param buffer buffer to use for copying |
41 | 44 | * @return the number of bytes copied
|
42 | 45 | * @throws IOException in case of I/O errors
|
43 | 46 | */
|
44 |
| - public static long copy(final InputStream in, final OutputStream out) throws IOException { |
| 47 | + public static long copy(final InputStream in, final OutputStream out, byte[] buffer, boolean close) throws IOException { |
45 | 48 | Exception err = null;
|
46 | 49 | try {
|
47 |
| - final long byteCount = in.transferTo(out); |
| 50 | + long byteCount = 0; |
| 51 | + int bytesRead; |
| 52 | + while ((bytesRead = in.read(buffer)) != -1) { |
| 53 | + out.write(buffer, 0, bytesRead); |
| 54 | + byteCount += bytesRead; |
| 55 | + } |
48 | 56 | out.flush();
|
49 | 57 | return byteCount;
|
50 | 58 | } catch (IOException | RuntimeException e) {
|
51 | 59 | err = e;
|
52 | 60 | throw e;
|
53 | 61 | } finally {
|
54 |
| - IOUtils.close(err, in, out); |
| 62 | + if (close) { |
| 63 | + IOUtils.close(err, in, out); |
| 64 | + } |
55 | 65 | }
|
56 | 66 | }
|
| 67 | + |
| 68 | + /** |
| 69 | + * @see #copy(InputStream, OutputStream, byte[], boolean) |
| 70 | + */ |
| 71 | + public static long copy(final InputStream in, final OutputStream out, boolean close) throws IOException { |
| 72 | + return copy(in, out, buffer.get(), close); |
| 73 | + } |
| 74 | + |
| 75 | + /** |
| 76 | + * @see #copy(InputStream, OutputStream, byte[], boolean) |
| 77 | + */ |
| 78 | + public static long copy(final InputStream in, final OutputStream out, byte[] buffer) throws IOException { |
| 79 | + return copy(in, out, buffer, true); |
| 80 | + } |
| 81 | + |
| 82 | + /** |
| 83 | + * @see #copy(InputStream, OutputStream, byte[], boolean) |
| 84 | + */ |
| 85 | + public static long copy(final InputStream in, final OutputStream out) throws IOException { |
| 86 | + return copy(in, out, buffer.get(), true); |
| 87 | + } |
57 | 88 | }
|
0 commit comments