|
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