您的位置:首页 > 运维架构 > Apache

com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException :1字节的 UTF-8 序列的字节 1 无效

2018-01-11 09:54 661 查看
最近做Ftp文件操作,发现读取ftp的xml文件时,把读取到的流放到工具类转成document就会报错,报错信息如标题所示。

报错原因分析:

我为了复现读取ftp服务器上的xml文件流异常原因,就把ftp上的文件先拿到本地,用工具类读取对应的流,报错信息和直接读取ftp的流一样。然后我把拿过来的文件另存为UTF-8的编码方式,在用工具类读取就不出现异常。说明问题确实 是xml文件的编码方式问题导致的。



我们正常新建一个文本文档,保存默认的编码方式是ANSI,而ANSI在Windows系统的编码处理中,ANSI编码一般代表系统默认编码方式,而且并不是确定的某一种编码方式——在简体中文操作系统中ANSI编码默认指的是GB系列编码(GB2312、GBK、GB18030);在繁体中文操作系统中ANSI编码默认指的是BIG5;在日文操作系统中ANSI编码默认指的是Shift JIS,等等。可在系统区域设置的系统Locale中更改。

这也是为什么选择UTF-8编码则不会异常,选择ANSI会异常的原因,就是因为UTF-8指定死了编码方式,在任何local环境中都不会变,相当于没有设置编码方式,ANSI会随着local而编码方式发生改变。由于windows简体中文的编码格式为GBK,所以读进来inputstream的编码就是gbk!,但是我们XML工具读取流转成String或者Document时,看源码你会看到这样一句话:

/**
*the encoding must be a string acceptable for an XML encoding declaration (see section 4.3.3 of the XML 1.0 recommendation)
*译文:编码必须是XML编码声明可以接受的字符串(参见XML 1.0推荐的第4.3.3节)
**/
public void setEncoding(String encoding){
this.encoding=encoding
}


当我们用工具类:
XMLUtils.parse(inputStream)
时,由于读取的xml本身设置了编码方式为utf-8:
<?xml version="1.0" encoding="utf-8">
,所以会读取编码为utf-8的流时,而流默认编码是系统的gbk,就会异常。

分析完原因,下面看下如何解决吧~

解决办法:

1.如果能通过直接修改xml文件本身的编码方式,就保存为utf-8形式。就可以了。

2.如果第一种方式行不通。就可以先通过把InputStream转成编码方式为gbk的InputStreamReader,然后工具类读取这个reader就可以。

具体部分代码截取示例:

a.开始读取流有问题的代码

in=ftpClient.retrieveFileStream(directory);
document=XMLUtils.parse(in);


异常报错:

com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException :1字节的 UTF-8 序列的字节 1 无效。


4000
b.修改后能正常转成documen的代码

in=ftpClient.retrieveFileStream(directory);
InputStreamReader reader=new InputStreamReader(in,Charset.forName("GBK"));
document=XMLUtils.parse(reader);


参考博文:刨根究底字符编码之七——ANSI编码与代码页(Code Page)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐