Avoid reading char by char by using a 4k buffer

This also removes the need for BufferedReader.
Use StringBuilder instead of StringBuffer
Merge remote-tracking branch 'upstream/master'