【问题标题】:Why Groovy file write with UTF-16LE produce BOM char?为什么用 UTF-16LE 写入 Groovy 文件会产生 BOM 字符?
【发布时间】:2015-08-12 20:15:59
【问题描述】:

您知道为什么下面的第一行和第二行不生成文件的 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。

【问题讨论】:

  • 欢迎来到 StackOverflow。我认为字符集不区分大小写(它应该在 Java 中),但没有任何文档可以确认,我只能假设 utf-16le(小写)告诉 withPrintWriter() 不要发出 BOM,@987654328 @(大写)告诉它发出一个 BOM。这是此示例中的唯一区别。 UnicodeLittleUnmarked 强制跳过 BOM,UnicodeLittle 强制跳过 BOM,但也许 utf-16le/UTF16-LE 在 Groovy 中更模糊?
  • 我也使用 Java 和 PrintWriter 进行了测试,这些编码都不会产生 BOM。我认为这是正确的。如果我定义为 LE 或 BE。无需设置 BOM。如果我只使用 UTF-16,Java 用 Little Endian 写入文件,并且还有 BOM 在 groovy 中似乎 utf-16 和 UTF-16 产生 BOM。

标签: encoding groovy utf-16le


【解决方案1】:

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 新的 PrintWriter 20 00

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

我不确定这种行为差异是否是故意的。我对此很好奇,所以我在mailing listasked。那里的人应该知道设计背后的历史。

编辑:GROOVY-7465 是根据上述讨论创建的。

【讨论】:

  • 我再补充一些例子
  • 谢谢。这些例子有助于澄清你的问题。我已经编辑了我的答案。
猜你喜欢
  • 2022-06-14
  • 2021-05-10
  • 2010-12-28
  • 1970-01-01
  • 1970-01-01
  • 2010-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多