Запись Unicode в RTF-файл - PullRequest
       23

Запись Unicode в RTF-файл

2 голосов
/ 25 октября 2011

Я пытаюсь записать строки на разных языках в файл 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);

Вы можете использовать байт [] непосредственно в выходном потоке с методом записи.Все вышесказанное дает мне искаженные символы для всего, кроме западноевропейских языков.Чтобы проверить, работает ли он, я попытался открыть документ с результатами в notepad ++ и установить соответствующую кодировку.Также я использовал OpenOffice, где вы можете выбрать кодировку и шрифт при открытии документа.

Если он работает, но мой компьютер не может открыть его правильно, есть ли способ проверить это?

Ответы [ 3 ]

3 голосов
/ 26 октября 2011

DataOutputStream outStream;

Возможно, вам не нужен DataOutputStream для записи файла RTF.DataOutputStream предназначен для записи двоичных структур в файл, но RTF основан на тексте.Обычно для OutputStreamWriter установка соответствующего набора символов в конструкторе будет способом записи в текстовые файлы.

outStream.writeBytes (strJapanese);

В частности, это терпит неудачу, потому что writeBytes действительно записывает байты, даже если вы передаете ему String.Гораздо более подходящим типом данных был бы byte[], но это только одно из тех мест, где Java обрабатывает байты и символы вводит в заблуждение.Он преобразует вашу строку в байты просто, беря младшие восемь бит каждой кодовой единицы UTF-16 и выбрасывая остальные.Это приводит к кодированию ISO-8859-1 с искаженной ерундой для всех символов, которых нет в ISO-8859-1.

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

Это на самом деле ничего полезного не дает.Вы кодируете в байты UTF-8, а затем декодируете это обратно в строку, используя кодировку по умолчанию.Почти всегда ошибка касаться кодировки по умолчанию, так как она непредсказуема на разных машинах.

outStream.writeUTF(strJapanese);

Это было бы лучшим ударом при написании UTF-8, но это все же не совсем правильно, так как использует поддельные Java«Модифицированная кодировка UTF-8» и, что более важно, файлы RTF на самом деле не поддерживают UTF-8 и вообще не должны напрямую включать символы не-ASCII.

Традиционно символы не-ASCII из 128вверх должен быть записан как шестнадцатеричные байты, такие как \'80, и кодировка для них указана, если она вообще есть, в экранированных шрифтах \fcharset и \cpg, которые очень, очень раздражают иметь дело, и нене предлагайте UTF-8 в качестве одного из вариантов.

В более современных RTF вы получаете \u1234x выходов, как в ответе Дабблера (+1).Каждый escape кодирует одну кодовую единицу UTF-16, что соответствует Java char, поэтому не так уж сложно заменить все символы, не входящие в ASCII, на их экранированные варианты.

Это поддерживается в Word 97и позже, но некоторые другие инструменты могут игнорировать Unicode и возвращаться к символу замены x.

RTF - не очень хороший формат.

3 голосов
/ 26 октября 2011

По умолчанию строки в JAVA представлены в формате 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();
}

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

2 голосов
/ 25 октября 2011

Вы можете написать любой символ Unicode, выраженный как его десятичное число, используя управляющее слово \u.Например, \u1234? будет представлять символ, у которого кодовая точка Unicode равна 1234, а ? является символом замены для случаев, когда символ не может быть адекватно представлен (например, потому что шрифт не содержит его).

...