Какую кодировку символов использует метод writeObject ObjectOutputStream?

Я читал, что Java использует внутреннюю кодировку UTF-16. т.е. я понимаю, что если мне нравится: String var = "जनमत"; тогда "जनमत" будет внутренне закодирован в UTF-16. Итак, если я сброшу эту переменную в какой-нибудь файл, например, ниже:

fileOut = new FileOutputStream("output.xyz");
out = new ObjectOutputStream(fileOut);
out.writeObject(var);

будет ли строка «जनमत» в файле output.xyz кодироваться в UTF-16? Кроме того, позже, если я захочу читать из файла output.xyz через ObjectInputStream, смогу ли я получить представление переменной в формате UTF-16?

Спасибо.


person bikashg    schedule 08.12.2010    source источник
comment
Я не думаю, что вам следует заботиться о кодировке, используемой ObjectOutputStream. Если вы собираетесь использовать сгенерированный файл в другом месте, просто не используйте ObjectOutputStream. Если нет, не нужно об этом думать.   -  person khachik    schedule 08.12.2010
comment
вы действительно не должны напрямую помещать символы, отличные от ASCII, в исходный файл .java, это обсуждалось здесь и там до тошноты. По сути, файлы .java не имеют связанных с ними метаданных, указывающих, в какой кодировке они закодированы, или какой-либо спецификации, требующей какой-либо конкретной кодировки. Следовательно, дерьмо ДОЛЖНО рано или поздно поразить поклонников, когда вы смешиваете операционные системы, IDE, текстовые редакторы, инструменты (сценарии пакетной обработки / оболочки) и т.д. другие файлы (для которых у вас есть полный контроль над их кодировкой) или используйте экранирование \ uXXXX Java.   -  person SyntaxT3rr0r    schedule 08.12.2010
comment
чтобы ответить на ваш вопрос, нет, тот факт, что Java может или не может использовать UTF-16 или UCS-2 (или цвета лунных ботинок, которые мало боятся носить) для внутреннего хранения строк, вообще не влияет на кодировку, используемую при сохранении указанная строка в файл.   -  person SyntaxT3rr0r    schedule 08.12.2010


Ответы (3)


Итак, если я сброшу эту переменную в какой-то файл ... будет ли кодировка строки «जनमत» в файле «output.xyz» в UTF-16?

Кодировка вашей строки в файле будет в том формате, в котором ObjectOutputStream хочет ее поместить. Вы должны рассматривать ее как черный ящик, который может быть прочитан только ObjectInputStream. (Серьезно - даже несмотря на то, что формат IIRC хорошо документирован, если вы хотите прочитать его с помощью какого-либо другого инструмента, вам следует сериализовать объект самостоятельно как XML, JSON или что-то еще.)

Позже, если я захочу читать из файла output.xyz через ObjectInputStream, смогу ли я получить представление переменной в формате UTF-16?

Если вы прочитаете файл с ObjectInputStream, вы получите обратно копию исходного объекта. Это будет включать java.lang.String, который представляет собой простой поток символов (не байтов), из которого вы можете получить представление UTF-16, если хотите, через getBytes () (хотя я подозреваю, что вам это действительно не нужно) .


В заключение, не беспокойтесь о внутренних деталях сериализации. Если вам нужно знать, что происходит, создайте файл самостоятельно; а если вам просто любопытно, верьте, что JVM сделает все правильно.

person Andrzej Doyle    schedule 08.12.2010

Близко: это не совсем UTF-16, а что-то вроде UCS-2; но в любом случае он использует 2 байта для большинства символов (и последовательность из 2 символов, т.е. 4 байта для некоторых редко используемых кодовых точек).

ObjectOutputStream использует так называемый модифицированный UTF-8, который похож на UTF-8, но где нулевой символ выражается как 2-байтовая последовательность, что недопустимо в соответствии с UTF-8 (из-за ограничений уникальности кодирования), но такого рода естественным образом декодирует вернуться к значению 0.

Но на самом деле вы спрашиваете: «Работает ли это так, что я пишу строку, читаю строку» - и отвечаю на это «да». JDK выполняет правильное кодирование при записи байтов и декодирование при чтении.

Как бы то ни было, вам лучше использовать метод writeUTF () для строк, поскольку я думаю, что результат будет немного более компактным. но "writeObject ()" тоже работает, просто нужно немного больше метаданных.

person StaxMan    schedule 08.12.2010

Чтобы добавить к этому, ObjectOutputStream.writeString() будет определять длину UTF данной строки и записывать ее в "стандартном" UTF или в "длинном" формате UTF, где "long", как указано в javadoc

«Длинный» формат UTF идентичен стандартному UTF, за исключением того, что в нем используется 8-байтовый заголовок (вместо стандартных 2-х байтов) для передачи длины кодировки UTF.

Я получил это из кода ...

private void writeString(String str, boolean unshared) throws IOException {
    handles.assign(unshared ? null : str);
    long utflen = bout.getUTFLength(str);
    if (utflen <= 0xFFFF) {
        bout.writeByte(TC_STRING);
        bout.writeUTF(str, utflen);
    } else {
        bout.writeByte(TC_LONGSTRING);
        bout.writeLongUTF(str, utflen);
    }
}

и в writeObject(Object obj) они делают проверку

if (obj instanceof String) {
    writeString((String) obj, unshared);
}
person Buhake Sindi    schedule 08.12.2010