Avoid reading char by char by using a 4k buffer

This also removes the need for BufferedReader.
Use StringBuilder instead of StringBuffer