Я пишу несколько процедур маршалинга/демаршалинга для проекта класса и немного озадачен поведением Java по умолчанию в этом случае. Вот мои «наивные» подпрограммы для записи и чтения строк в потоки байтов и из них:
protected static void write(DataOutputStream dout, String str)
throws IOException{
dout.writeInt(str.length());
dout.writeChars(str);
}
protected static String readString(DataInputStream din)
throws IOException{
int strLength = 2*din.readInt(); // b/c there are two bytes per char
byte[] stringHolder = new byte[strLength];
din.read(stringHolder);
return new String(stringHolder);
}
К сожалению, это просто не работает; символы записываются в формате UTF-16 по умолчанию, но String(byte[])
, похоже, предполагает, что каждый байт будет содержать символ, и, поскольку все символы ASCII начинаются с 0 байта в UTF-16, конструктор просто отказывается и возвращает пустой строки. Решение состоит в том, чтобы изменить readString
, чтобы указать, что он должен использовать кодировку UTF-16:
protected static String readString(DataInputStream din)
throws IOException{
int strLength = 2*din.readInt();
byte[] stringHolder = new byte[strLength];
din.read(stringHolder);
return new String(stringHolder, "UTF-16");
}
У меня вопрос, зачем это нужно? Поскольку Java по умолчанию использует UTF-16 для строк, почему бы не предположить, что UTF-16 используется при чтении символов из байтов? Или, в качестве альтернативы, почему бы ему просто не кодировать символы как байты по умолчанию? Короче говоря, почему поведение по умолчанию метода writeChars()
и конструктора String(byte[])
не параллельно друг другу?
DataOutputStream.writeUTF()
иDataInputStream.readUTF()
? - person Boris the Spider   schedule 18.02.2013