PY3: use six.BytesIO and six.moves.cStringIO

I've followed some code and found that most of the content are binary, so I use `six.BytesIO` here (there's one exception that I still use StringIO for). I'm not sure if it's the best solution since it means `StringIO.StringIO` but not `cStringIO.StringIO` in Python 2.x, so performance can be affected.

An alternative way would be a try-except block to import `cStringIO.StringIO` first, and fallback to `io.BytesIO`.
Ha, no idea actually.

AFAICS we can change it to isinstance :)

(PS: I have a big git stash about unicode, basestring, str, and so on, but still needs more effort to make sure I get each of them correct in the context)