First of all, I think you have one misunderstanding about FileReader. To be honest, this class is quite rubbish. It won't read the real encoding of the file, but assumes the system default is used. A better solution is use InputStreamReader around a FileInputStream and manually specify the encoding.
I know that I mentioned using FileReader before, and it's still good if the system default encoding is used, but only then.
There is one huge flaw in your code.
That reading is as it should; the writing isn't though. First of all, the third parameter is the number of characters to write. Even if you need to write the entire array, that parameter should be cbuf.length, not cbuf.length - 1. This way you're missing one character most of the time.
That said,
you should never assume that you'll need to write the entire array. Although it's probably true for files for most iterations, it's wrong most of the time for the last iteration. Your file size will most likely not be a multiple of 20. If your file size is 32 your code will first write 19 characters (ignoring number 20), then write another 19, where only 12 should be written.
That's where b comes into play. It's the number of characters actually read into cbuf. Therefore, that's also the number of characters to write: