将unicode写入rtf文件

时间:2011-10-25 19:32:12

标签: java unicode encoding rtf dataoutputstream

我正在尝试将不同语言的字符串写入rtf文件。我尝试了一些不同的东西。 我在这里使用日语作为例子,但我尝试过的其他语言也是如此。

public void writeToFile(){

    String strJapanese = "日本語";
    DataOutputStream outStream;
    File file = new File("C:\\file.rtf");

    try{

        outStream = new DataOutputStream(new FileOutputStream(file));
        outStream.writeBytes(strJapanese);
        outStream.close();

    }catch (Exception e){
        System.out.println(e.toString());
    }
}

我也尝试过:

byte[] b = strJapanese.getBytes("UTF-8");
String output = new String(b);

或更具体:

byte[] b = strJapanese.getBytes("Shift-JIS");
String output = new String(b);

输出流也有writeUTF方法:

outStream.writeUTF(strJapanese);

您可以使用write方法直接在输出流中使用byte []。除了西欧语言之外,以上所有内容都为我提供了乱码。为了查看它是否有效,我尝试在notepad ++中打开结果文档并设置适当的编码。此外,我使用OpenOffice,您可以在打开文档时选择编码和字体。

如果它确实有效,但我的电脑无法正常打开,有没有办法检查?

3 个答案:

答案 0 :(得分:3)

  

DataOutputStream outStream;

您可能不希望DataOutputStream用于编写RTF文件。 DataOutputStream用于将二进制结构写入文件,但RTF是基于文本的。通常,OutputStreamWriter设置适当的charset in the constructor将是写入文本文件的方式。

  

outStream.writeBytes(strJapanese);

特别是失败,因为writeBytes确实写入了字节,即使你传递了一个字符串。一个更合适的数据类型应该是byte[],但这只是Java处理字节与字符混淆的地方之一。将字符串转换为字节的方式只需要取每个UTF-16代码单元的低8位,然后将其余部分丢弃。这导致ISO-8859-1编码对ISO-8859-1中不存在的所有字符都有乱码。

byte[] b = strJapanese.getBytes("UTF-8");
String output = new String(b);

这实际上没有任何用处。您编码为UTF-8字节,然后使用默认字符集将其解码回String。触摸默认字符集几乎总是一个错误,因为它在不同的机器上是不可预测的。

outStream.writeUTF(strJapanese);

这对编写UTF-8更好,但它仍然不太正确,因为它使用Java伪造的“修改过的UTF-8”编码,更重要的是RTF文件实际上并不支持UTF-8,并且不应该根本不包含任何非ASCII字符。

传统上,128以上的非ASCII字符应该写为像\'80这样的十六进制字节转义符,并且如果它完全是字体\fcharset和{{1},则指定它们的编码处理非常非常烦人的转义,并且不提供UTF-8作为选项之一。

在更现代的RTF中,你会得到\cpg,就像Dabbler的回答(+1)一样。每个转义编码一个UTF-16代码单元,它对应于Java \u1234x,因此用正则表达式替换所有非ASCII字符的转义变种并不太难。

Word 97及更高版本支持此功能,但其他一些工具可能会忽略Unicode并回退到char替换字符。

RTF格式不是很好。

答案 1 :(得分:3)

默认情况下,JAVA中的stings是UTF-8(unicode),但是如果要将其写下来,则需要指定编码

try {
    FileOutputStream fos = new FileOutputStream("test.txt");
    Writer out = new OutputStreamWriter(fos, "UTF8");
    out.write(str);
    out.close();
} catch (IOException e) {
    e.printStackTrace();
}

参考:http://download.oracle.com/javase/tutorial/i18n/text/stream.html

答案 2 :(得分:2)

您可以使用\u控制字来编写以十进制数表示的任何Unicode字符。例如。 \u1234?表示Unicode代码点为1234的字符,?是字符无法充分表示的情况的替换字符(例如,因为字体不包含它)。