JAVA判断输入流字符编码的困惑
来源:互联网 发布:linux echo 创建文件 编辑:程序博客网 时间:2024/06/06 21:39
近日在开发爬虫程序时发现,如果事先不指定正确的字符集编码,在得到InputStream字节流实例后使用程序自身去判断,相关代码如下
Java代码
- if(charset == null || "".equals(charset)) {
- reader = new InputStreamReader(inputStream);
- charset = reader.getEncoding();
- }else {
- reader = new InputStreamReader(inputStream, charset);
- }
在if块语句中,往往会得到错误的charset,原因是创建了一个使用系统平台字符集的 InputStreamReader实例,同时很多专业网站在制作时使用了一个小技巧,就是在文件开头敲空格等,这样就会造成JDK的相关类在判断抓取到的输入流是什么编码出现错误,继而抓取下来的都是包含乱码的网页。例如抓取http://www.chinahr.com首页代码,根据if中的程序判断,charset=”UTF8”,而页面实际设置了charset=”gb2312”。从这里也可看出JDK在底层的字节流,字符流的实现上仍然是不够成熟,容易出现错误。
因为在构成InputStreamReader实例时的字符集出错,所以即使对抓取到的乱码的网页字符串重新转码也得不到正确的结果。
由于inputStream字节流只允许读取一遍,往往还不支持mark(int),reset()等方法,所以根据这个特性,思考了若干解决方案,其中比较接近的一个是,先使用缺省字符集将字节流inputStream转换为字符流InputStreamReader,再使用BufferedReader类包装一层,在BufferedReader读取到包含charset的时候,对charset进行判断后,重新实例化InputStreamReader,然后接着逐行读取。代码如下:
- //原始的BufferedReader实例,reader即为上面代码产生的实例
- bufferedReader = new BufferedReader(reader);
- boolean mark = false;
- StringBuffer buffer = new StringBuffer();
- String str = "";
- int count = 0;
- while ((str = bufferedReader.readLine()) != null) {
- if(mark && count > 0) {
- bufferedReader.reset();
- count = 0;
- }
- buffer.append(str).append("/n");
- if(!mark){
- count ++;
- String tempStr = str.toLowerCase();
- if(tempStr.indexOf(DetectorConstants.HtmlTagProperty.HTTP_EQUIV) != -1
- && tempStr.indexOf(DetectorConstants.HtmlTagProperty.CHARSET) != -1){
- //此处略过了实际分析过程,直接给出结果
- String anotherCharset = "gb2312";
- if(anotherCharset != null && !"".equals(anotherCharset) && !anotherCharset.equals(charset)){
- charset = anotherCharset;
- reader = new InputStreamReader(urlStream, anotherCharset);
- bufferedReader = new BufferedReader(reader);
- int av = urlStream.available();
- bufferedReader.mark(av + 1);//也可以使用count试试
- mark = true;
- }
- }
- }
- }
这种方法可以得到正确的编码格式的page页面,然而由于使用不同的字符集实例化InputStreamReader,造成inputStream流在使用新的字符集重新实例化后,之前的定位发生变化,前后的位置不一致,中间往往会漏掉大约400多行字符。
研究了一些相关开源项目,例如HtmlParser,发现也是无法提供一个正确的,好用的方法来判断字节流的编码格式。
来源:http://hi.baidu.com/%D0%A1%C2%EC%D2%CF_google/blog/item/14b41255e5ae9c55d00906e2.html
- JAVA判断输入流字符编码的困惑
- JAVA判断输入流字符编码的困惑
- JAVA判断输入流字符编码的困惑
- java判断字符编码格式
- python字符编码的判断
- java之判断输入的字符类型个数
- java中判断字符编码的格式以及转码
- JAVA字符的编码
- JAVA字符的编码
- Java的字符编码
- Java 判断输入是否为英文字符
- 判断字符窜的编码与转换字符窜编码
- 用于判断字符结尾的输入流类
- 字符编码之困惑(Unix/DOS)
- 小结一下我困惑Python字符编码
- Java中面向字符的输入流
- java的IO流之字符编码
- 输入字符类型的半判断
- C++ 关键字 作用
- 用RSA公钥加密与私钥加密及其解密方法--源代码
- 对比,区别或统一这些概念
- 面试题,看思维敏捷程度
- basicexcel 使用
- JAVA判断输入流字符编码的困惑
- 在CListCtrl的每个项都显示不同的提示信息(CToolTipCtrl)
- 基础shell编程-------shell学习(12)
- 解决数据库系统中存在的半个汉字问题
- visual studio 2008 与 vc6.0 区别1
- ubuntu下svn的安装与配置(转)
- assign连续赋值
- JDBC连接数据库的例子(oracle)
- Linux下安装memcached