Java:InputStreamReader字符编码需要运行两次

时间:2016-07-06 13:06:36

标签: java encoding inputstream

因此,我的公司与世界各地的客户进行了大量的XML转换工作。因此,我们有时会遇到字符编码问题。我们有一个应用程序的组件,旨在将InputStream规范化为特定的字符编码。它运作良好......但有一个问题。

在某些情况下,我们需要运行两次。对于我的生活,我无法告诉你为什么,我一直在努力弄清楚造成它的原因,我什么也没想出来。似乎有一些文件,当它第一次运行时,它没有做到正确,但是当它第二次运行时,一切都是好的。

以下是执行编码的代码(假设"编码"变量是" UTF-8",它通常是):

char[] buffer = new char[getBufferSize()];
String encoding = getEncoding();

Cache fileCache = getFileCache();

try (InputStreamReader reader = new InputStreamReader(data.getDataStream(), encoding); Writer writer = fileCache.getWriter(encoding)) {
    int charsRead;
    while ((charsRead = reader.read(buffer)) != -1) {
        writer.write(buffer, 0, charsRead);
    }
    data.setDataStream(fileCache.getInputStream());
} catch(IOException ex) {
    throw new Exception(String.format("Unable to normalize stream for %s encoding", encoding), ex);
}

因此,有时需要运行此代码两次以使流正确地使用指定的编码。

我正在寻求帮助:让它在第一次尝试时运行得更好。

1)这个问题有什么可能的原因?

2)有没有办法改进此代码以使"流规范化" (我们称之为)更有效吗?

3)除了使用InputStreamReader之外,还有哪些其他固定流编码方法可以更好地工作?

非常感谢。

1 个答案:

答案 0 :(得分:2)

使用XML时存在一些小问题:第一行<?xml ... ?>指定编码或默认为UTF-8。因此,XML通常被读作InputStream(二进制)并留给XML解析器来查找编码。

在编写XML时,可以假设它在字符串中说出来。从<?xml ... ?>编写new OutputStreamWriter(ouputStream, encoding)编码时,应使用<?xml encoding=...?>

必须在程序员的编辑器(如JEdit或Notepad ++)中测试二进制输入和输出XML的编码,以处理编码。

如果你想以正确的编码立即阅读文本:我搜索了XMLInputStreamReader并找到了一些。但是所有的Reader类都需要做:缓冲ByteArrayOutputStream中的第一个字节,直到处理package com.test; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; public class Test { public static class A { public static void sayHello() { System.out.println("Hello World"); } } public static class B extends A { public static void sayBye() { System.out.println("Goodbye cruel world"); } } public static void main(String[] args) throws Exception { // Java's Behavior A.sayHello(); // Works B.sayBye(); // Works B.sayHello(); // Works // Java Nashorn's Behavior ScriptEngineManager factory = new ScriptEngineManager(); ScriptEngine engine = factory.getEngineByName("nashorn"); engine.eval("var A = Java.type('com.test.Test.A')"); engine.eval("var B = Java.type('com.test.Test.B')"); engine.eval("A.sayHello()"); // Works engine.eval("B.sayBye()"); // Works engine.eval("B.sayHello()"); // Fails } } ,然后执行一个InputStreamReader。