Depending on how much I/O you will be performing, there can be a lot of benefits to using a buffer. Ideally, you should limit the number of calls to your input source, and read the bytes in as chunks.
Imagine a bucket with 10 pebbles, and you want to move them to another bucket. You could grab a handful of pebbles and just move them over. You don't need to go grab a shovel, that's to much overhead. But if the bucket has thousands of pebbles, you are going to want a shovel, and it is worth the effort to get get the shovel (in this analogy, the buffer is the shovel)... The moral of the story is that you should use a buffer when you are going to be making lots of calls to the data source.
This article may explain it better, and in more detail... http://pzemtsov.github.io/2015/01/19/on-the-benefits-of-stream-buffering-in-Java.html
Here is a link to the Oracle's website explaining how the PrintWriter class works. https://docs.oracle.com/javase/7/docs/api/java/io/PrintWriter.html
Here is a working example... You can use the PrintWriter class to write to the console if you instantiate the object with System.in. Be sure to also pass in "true" so that it will auto-flush.
import java.io.*;
public class PrintWriterExample
{
public static void main(String args[]) throws IOException
{
int [] id = {12456, 323, 345, 3423};
String [] firstName = {"John", "Paul", "George", "Ringo"};
String [] lastName = {"Lennon", "McCartney", "Harrison", "Star"};
PrintWriter outFile = new PrintWriter(System.out, true);
String format = "ID: %5d (%s, %s)\n";
for (int i=0; i<id.length; i++)
{
outFile.printf(format, id[i], firstName[i], lastName[i]);
}
}
}
Here is the output:
ID: 12456 (John, Lennon)
ID: 323 (Paul, McCartney)
ID: 345 (George, Harrison)
ID: 3423 (Ringo, Star)