从网页上获取数据时必须要注意字符集的问题。处理不慎确实苦不堪言。
例如通过URL连接时,将字节流InputStream包装成字符流(以便直接存为String)时,一定要注意加上charsetName这一参数。函数原型为
InputStreamReader(InputStream in, String charsetName) //创建使用指定字符集的 InputStreamReader。
此时将该参数设为相应网页使用的字符集即可。(一般为UTF-8或GBK等)
举个例子。
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setConnectTimeout(80000);
conn.setRequestMethod("GET");
conn.connect();
//将输入流转换为字符流
BufferedReader bufReader = new BufferedReader(
new InputStreamReader(
conn.getInputStream()
,"UTF-8"
)
);
//假定数据仅有一行
String result=bufReader.readLine();
但如果在包装字符流的时候没有设置字符集,而试图先获取原始数据之后再转换的话仍是有问题的。原因我认为是字节流获取的数据在转为字符流中的数据时,即涉及到将byte编码为char,在使用默认GBK编码时,UTF8字节流中某些字节不能正确解码,被转换成GBK的乱码表示了,也就是InputStreamReader内部的字节数组(如果有的话),也和HttpURL返回的已经不一致了。
举个错误例子。
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setConnectTimeout(80000);
conn.setRequestMethod("GET");
conn.connect();
//将输入流转换为字符流
BufferedReader bufReader = new BufferedReader(
new InputStreamReader(
conn.getInputStream()
//,"UTF-8"无此参数将发生错误
)
);
//假定数据仅有一行
String result=bufReader.readLine();
String newResult=new String(result.getBytes("GBK"),"UTF-8");
//试图将网页中的UTF-8数据转换为GBK,此时部分数据无法正确转换