`
pengfeng
  • 浏览: 228791 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类
最新评论

OutputStreamWriter类getEncoding方法的应用

阅读更多

      今天在写打包程序时,发现了一个及其奇怪的问题,就是OutputStreamWriter.getEncoding()的应用,在官方文

档上解释是这样说的:

返回此流使用的字符编码的名称。

          如果此编码具有历史名称,则返回该名称;否则返回该编码的规范化名称。

          如果此实例是用 OutputStreamWriter(OutputStream, String) 构造方法创建的,则返回的由此编码生成的

惟一名称可能与传递给该构造方法的名称不一样。如果流已经关闭,则此方法可能返回 null

     (注意红色标记的关键字,就是问题的关键)

   在这里给大家推荐一个高效生成XML的开源项目WAX

http://www.ociweb.com/mark/programming/WAX.html),生成5000条数据100M左右的XML文件只需要20秒左右

的时间(个人感觉这个效率还是很强的),正是在使用该项目的过程中发现问题。问题描述如下:

 

        //在WAX.java源文件中有如下一段代码
        if (writer instanceof OutputStreamWriter) {
                encoding = ((OutputStreamWriter) writer).getEncoding();
            }

 

  而我在构造OutputStreamWriter对象时采用的是 OutputStreamWriter(OutputStream, String) 构造方法,传

递的字符编码是“UTF-8”,但是,通过OutputStreamWriter.getEncoding()返回的却是“UTF8”,这样,通过WAX

生成XML文件的XML declaration部分的encoding就变成了UTF8,导致生成的XML文件其它解析器无法解析。将

上面的一段源码进行修改如下:

      if (writer instanceof OutputStreamWriter) {
            //encoding = ((OutputStreamWriter) writer).getEncoding();
            //pengfeng modify
            encoding = Charset.forName(((OutputStreamWriter) writer).getEncoding()).name();
        }

    OK,一切问题解决!

    呵呵,上面只说了问题的解决办法,该办法主要来源于http://jira.codehaus.org/browse/WSTX-146,引用如下:

 

   The code in the attached unit test incorrectly creates a document with an encoding in the XML
declaration of 'UTF8'. According to section 4.3.3 of the XML 1.0 spec, all XML parsers must support
encoding 'UTF-8', but not 'UTF8'. So many parsers including Xerces, won't parse that document.

The problem appears to be caused by the following code in WstxOutputFactory:

 

// we may still be able to figure out the encoding:
            if (enc == null) {
                if (w instanceof OutputStreamWriter) {
                    enc = ((OutputStreamWriter) w).getEncoding();
                }
            }

   According to the Javadoc for OutputStreamWriter.getEncoding(), "If the encoding has an historical

name then that name is returned; otherwise the encoding's canonical name is returned." The historical

name for UTF-8 is UTF8.

I believe the correct code would be:

// we may still be able to figure out the encoding:
            if (enc == null) {
                if (w instanceof OutputStreamWriter) {
                    enc = Charset.forName(((OutputStreamWriter) w).getEncoding()).name();
                }
            }

Tatu Saloranta added a comment - 18/Mar/08 02:09 PM
Thanks! This does indeeed look like sub-optimal behavior. As a work-around, applications shouldn't
rely on auto-detection of the encoding, but I definitely want to improve this auto-detection as well.

One minor note: since Charset class was introduced in JDK 1.4, the fix as suggested can only be added

to Woodstox 4.0. For 3.2, if the fix is to be backported I could just add specific work-around for UTF-8,

since that is likely to be the most common case (additionally if others are identified they can be added

of course).

I will fix this shortly for trunk (4.0).

 

Tatu Saloranta added a comment - 26/Mar/08 12:57 PM
Easy to fix, will call Charset.normalize() for the value (which already knows many legacy conversions).
I think I'll also backport it to 3.2.x, since there's no API change and this should be a safe fix.
分享到:
评论

相关推荐

    (超赞)JAVA精华之--深入JAVA API

    1.2.4 在方法中定义内部类 1.2.5 匿名内部类 1.2.6 内部类使用的其它的问题 1.3 文件和流 1.3.1 什么是数据流 1.3.2 InputStream 的方法有: 1.3.3 OutputStream 的方法: 1.3.4 File 类 1.3.5 文件流的建立 1.3.6 ...

    java编程基础,应用与实例

    13.4.1 InputStreamReader、OutputStreamWriter 191 13.4.2 BufferedReader与BufferedWriter 191 13.4.3 FileReader与FileWriter 193 13.4.4 从System.in获取数据 193 13.4.5 PrintStream与PrintWriter ...

    JAVA SE学习精华集锦

    1.2.4 在方法中定义内部类 49 1.2.5 匿名内部类 49 1.2.6 内部类使用的其它的问题 50 1.3 文件和流 51 1.3.1 什么是数据流 51 1.3.2 InputStream 的方法有: 51 1.3.3 OutputStream 的方法: 51 1.3.4 File 类 51 ...

    超级有影响力霸气的Java面试题大全文档

     声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,...

    IO流各个类的使用方法

    介绍了,下面这些类的具体使用方法,非常详细,值得一看 File FileFilter RandomAccessFile 【字节流】 InputStream OutputStream FileInputStream FileOutputStream DataInputStream DataOutputStream ...

    Java开发技术大全 电子版

    7.3.2OutputStreamWriter类中的方法250 7.3.3从键盘输入250 7.3.4文件复制251 7.4文件属性处理252 7.4.1File类中的方法252 7.4.2File类使用示例——文件列表253 7.5随机访问文件254 7.5.1RandomAccessFile类...

    lab-2-Alex-PtGa:GitHub Classroom创建的lab-2-Alex-PtGa

    OutputStreamWriter类 PrintWriter类。 属性文件(* .properties): 应用程序配置; Properties类; 读取属性文件; 字符串资源的本地化; ResourceBundle类。 进步 本实验是Java编程语言中的模

    java 面试题 总结

    声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其...

    JAVA基础课程讲义

    String类的常用方法(已讲过,不再讲!) 120 StringBuffer和StringBuilder 121 String和StringBuffer和StringBuilder使用要点 123 时间处理相关类 124 Date时间类(java.util.Date) 124 DateFormat类和...

    Java文件处理工具类--FileUtil

    OutputStreamWriter fout = new OutputStreamWriter(new FileOutputStream( fileName), encoding); fout.write(content); fout.close(); return true; } /** * Write binary byte array to local ...

    JDK_API_1_6

    OutputStreamWriter OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。 PipedInputStream 管道输入流应该连接到管道输出流;管道输入流提供要写入管道输出流的...

    Java中的InputStreamReader和OutputStreamWriter源码分析_动力节点Java学院整理

    本文通过示例代码给大家解析了Java中的InputStreamReader和OutputStreamWriter知识,需要的的朋友参考下吧

    Java 实现 POS 打印机无驱串口打印(解决中文乱码)

    再从这个端口列表中选择所需要的端口,并调用CommPortIdentifer对象的Open( )方法,这样,就能得到一个CommPort对象。当然,还要将这个CommPort对象的类型转换为某个非抽象的子类,表明是特定的通讯设备。该子类可以...

    Java 实现POS打印机无驱串口打印(解决中文乱码)修改版

    再从这个端口列表中选择所需要的端口,并调用CommPortIdentifer对象的Open( )方法,这样,就能得到一个CommPort对象。当然,还要将这个CommPort对象的类型转换为某个非抽象的子类,表明是特定的通讯设备。该子类可以...

    day019-io笔记和代码.rar

    3. IO流工具类的抽取,将所有的关流(字节流和字符流)方法抽取出来,优化代码 4. 字符流:(重点) * 使用场景:使用于处理文本相关的文件 * * Reader 抽象类: * |子类 * ...

    java生成properties文件工具类

    通过程序生成properties文件的工具类,并可根据添加顺序生成,可添加注释,调用步骤如下: 1.OutputOrderProperties p = new OutputOrderProperties(); 2.FileInputStream fs = new FileInputStream("文件路径"); 3....

    高阶JAVA篇-深入解读字符集.pptx.pptx

    Java字符编码基础 Java字符编码是处理文本信息的基础,它规定了...Java提供了丰富的API用于字符编码的处理,如Charset类可以获取系统默认的字符编码,InputStreamReader和OutputStreamWriter可以进行字符编码的转换。

    java io 类 小结 代码

    简洁分类 代码直接使用 ...InputStreamReader OutputStreamWriter BufferedReader BufferedWriter PrintWriter DataOutputStream DataInputStream ObjectOutputStream ObjectInputStream Scanner

    java经典面试2010集锦100题(不看你后悔)

    C) 抽象类中至少需要有一个方法被定义为抽象方法,在该方法前加abstract,把该方法定义为抽象方法。 D) 抽象类中可以没有抽象方法,即所有的方法全部都有实现体。但是依旧不能为抽象类定义对象。 题目18:b 下面...

    java代码-FileOutputStream与OutputStreamWriter FileInputStream与InputStreamReader append()函数,ready()函数,toString()函数

    java代码-FileOutputStream与OutputStreamWriter FileInputStream与InputStreamReader append()函数,ready()函数,toString()函数

Global site tag (gtag.js) - Google Analytics