为什么用UTF-16LE写Groovy文件会产生BOM char?

时间:2015-05-29 20:25:04

标签: encoding groovy utf-16le

你知道为什么下面的第一行和第二行不会对文件和第三行产生BOM吗?我认为UTF-16LE是正确的编码名称,并且编码不会自动创建BOM到文件的开头。

new File("foo-wo-bom.txt").withPrintWriter("utf-16le") {it << "test"}
new File("foo-bom1.txt").withPrintWriter("UnicodeLittleUnmarked") {it << "test"}
new File("foo-bom.txt").withPrintWriter("UTF-16LE") {it << "test"}

另一个样本

new File("foo-bom.txt").withPrintWriter("UTF-16LE") {it << "test"}
new File("foo-bom.txt").getBytes().each {System.out.format("%02x ", it)}

打印

ff fe 74 00 65 00 73 00 74 00

和java

        PrintWriter w = new PrintWriter("foo.txt","UTF-16LE");
        w.print("test");
        w.close();
        FileInputStream r = new FileInputStream("foo.txt");
        int c;
        while ((c = r.read()) != -1) {
            System.out.format("%02x ",c);
        }
        r.close();

打印

74 00 65 00 73 00 74 00

Java不会产生BOM,而Groovy则有BOM。

1 个答案:

答案 0 :(得分:0)

withPrintWriter的行为似乎有所不同。在GroovyConsole

中试试这个
File file = new File("tmp.txt")
try {
    String text = " "
    String charset = "UTF-16LE"

    file.withPrintWriter(charset) { it << text }
    println "withPrintWriter"
    file.getBytes().each { System.out.format("%02x ", it) }

    PrintWriter w = new PrintWriter(file, charset)
    w.print(text)
    w.close()
    println "\n\nnew PrintWriter"
    file.getBytes().each { System.out.format("%02x ", it) }
} finally {
    file.delete()
}

输出

withPrintWriter
ff fe 20 00 

new PrintWriter
20 00

这是因为调用new PrintWriter会调用Java构造函数,但调用withPrintWriter最终会调用org.codehaus.groovy.runtime.ResourceGroovyMethods.writeUTF16BomIfRequired()来编写BOM。

我不确定这种行为差异是否是故意的。我对此感到好奇,所以我askedmailing list了。有人应该知道设计背后的历史。

编辑:GROOVY-7465是在上述讨论中创建的。