To answer your main question: No, you cannot go directly from an InputStream
/ OutputStream
to a BufferedReader
/ BufferedWriter
. The problem is you need a class which can translate from an input/output stream, which deals directly with bytes, to a reader/writer, which deals with characters (i.e. by decoding bytes into characters and vice versa). As pointed out by @jaco0646's answer, this is one of the cons of the decorator pattern. Of course, you could make a utility method:
public static BufferedReader toBufferedReader(InputStream stream, Charset charset) {
return new BufferedReader(new InputStreamReader(stream, charset));
}
To make your other code shorter. Though I'm sure there's already a library out there that provides this (e.g. maybe Commons IO or Guava).
That all being said, you don't appear to need a reader or a writer. Your question indicates, and you later confirm in a comment, that you're simply downloading data directly into a file. This means you have no need to decode the bytes into characters only to immediately encode the characters back into bytes. You just need to transfer the bytes from the InputStream
to the OutputStream
directly. Here's some examples (staying within the JDK):
Manually copying the bytes using a buffer
public static void copyUrlToFile(URL url, File file) throws IOException {
try (InputStream input = url.openStream();
OutputStream output = new FileOutputStream(file)) {
byte[] buffer = new byte[1024 * 8]; // 8 KiB buffer
int read;
while ((read = input.read(buffer)) != -1) {
output.write(buffer, 0, read);
}
}
}
Could also use Path
and Files#newOutputStream(Path,OpenOption...)
instead of File
and FileOutputStream
.
public static void copyUrlToFile(URL url, File file) throws IOException {
try (InputStream input = url.openStream();
OutputStream output = new FileOutputStream(file)) {
input.transferTo(output);
}
}
public static void copyUrlToFile(URL url, Path file) throws IOException {
try (InputStream input = url.openStream()) {
Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
}
}
Note that, when using NIO, you can open buffered readers and writers to files directly using Files#newBufferedReader(Path)
and Files#newBufferedWriter(Path,OpenOption...)
, respectively.