当字符串未以UTF-8编码时抛出异常

时间:2012-11-27 14:01:23

标签: java xml

我有一个方法,其中一个输入属性是String xml。我只是想为该xml的编码创建控件。如果任何字符在UTF-8的其他编码中,则会抛出错误。

请告诉我如何创建和测试它的最简单方法?

我使用过这样的东西:

String xml = IOUtils.toString(new FileInputStream("c:/encoding.xml")); 
Document doc = builder.parse(IOUtils.toInputStream(xml, "UTF-8"));

添加了Ľ,Š,Ť,Ž,ľ,š,ť,ž等字母,并将其保存为cp1250文件。

但没有错误。

我做错了什么?

2 个答案:

答案 0 :(得分:2)

这不能在Java中本地完成。一个文件只是一个字节串,但是你可以解释它们,默认情况下Java无法添加含义。我建议使用这个库(不,我没有写它):

http://code.google.com/p/juniversalchardet/

按照以下说明操作(从该链接粘贴的副本):

如何使用

  1. 构建org.mozilla.universalchardet.UniversalDetector
  2. 的实例
  3. 通过调用UniversalDetector.handleData()将一些数据(通常为几千字节)提供给检测器。
  4. 致电UniversalDetector.dataEnd()
  5. 通知检测器数据结束
  6. 通过调用UniversalDetector.getDetectedCharset()获取检测到的编码名称。
  7. 在重复使用探测器实例之前,不要忘记调用UniversalDetector.reset()

答案 1 :(得分:1)

String xml = IOUtils.toString(new FileInputStream("c:/encoding.xml")); 

如果此IOUtilsorg.apache.commons.io.IOUtils,则其Javadoc表示

“使用平台的默认字符编码将InputStream的内容作为字符串获取。”

当您保存为cp1250时,我猜cp1250也是您的平台字符编码。你的代码将做的是

  1. 将文件作为字节流读取
  2. 使用cp1250(平台编码)
  3. 将字节流转换为字符
  4. 将字符转换为Java内部表示形式(UTF-16)
  5. 从UTF-16转换为UTF-8
  6. 创建XML文档
  7. 这将始终有效,因为cp1250 确实是您的文件编码,UTF-16包含cp1250中的每个字符,UTF-8包含UTF-16中的每个字符。

    如果要将字节读取为UTF-8并避免自动转换,则应使用IOUtils.toString()的双参数变体之一:

    public static String toString(InputStream input, Charset encoding)
    
    public static String toString(InputStream input, String encoding)
    

    所以我会尝试:

    // Helper import: I always forget if the constant is "UTF8" or "UTF-8"
    import org.apache.commons.lang.CharEncoding;
    
    String xml = IOUtils.toString(new FileInputStream("c:/encoding.xml"), CharEncoding.UTF_8); 
    Document doc = builder.parse(IOUtils.toInputStream(xml, CharEncoding.UTF_8));
    

    这里的经验法则是:从不执行任何字节到字符串/字符串到字节的转换,而不指定源/目标编码。

    一个小的经验法则是:除非你需要使用其他编码,否则在任何地方都使用UTF-8。

    这两条经验法则都与您选择的编程语言无关。