Standardmäßig wird alles, was Sie in Ihre UTF-8-Zeichenfolge eingeben, als ein Zeichen dekodiert. Wenn es sich nicht um eine gültige UTF-8-Sequenz handelt, wird das Ersatzzeichen (�
) verwendet - und erscheint weiterhin in Ihrer Ausgabe.
Sie können nur �
aus Ausgabezeichenfolge entfernen, aber es könnte auch aus Eingabezeichenfolge kommen. Stattdessen sollten Sie das zusätzliche Byte von UTF-8-Byte Streifen:
static String readString(final DataInputStream in) throws IOException {
int len = in.readUnsignedShort();
final byte[] bytes = new byte[len];
in.read(bytes);
if (bytes[len - 1] == -1) {
len--;
}
return new String(bytes, 0, len, UTF_8);
}
Eine weitere Option ist 0x0010
zu überspringen, wenn Länge codiert, und alle Werte oberhalb von 1 bewegen:
static void writeString(final DataOutputStream out, final String str) throws IOException {
final byte[] bytes = str.getBytes(UTF_8);
short len = (short) bytes.length;
if (bytes.length >= 0x0010) {
len++;
}
out.writeShort(len);
out.write(bytes);
}
static String readString(final DataInputStream in) throws IOException {
int len = in.readUnsignedShort();
if (len == 0x0010) {
throw new IllegalStateException();
} else if (len > 0x0010) {
len--;
}
final byte[] bytes = new byte[len];
in.read(bytes);
return new String(bytes, UTF_8);
}
Diese beiden Lösungen Hacks sind und wird wahrscheinlich in der Zukunft Probleme verursachen. Die korrekte Lösung wäre, diese künstliche Beschränkung zu entfernen:
- Wenn Sie das endgültige Format steuern, ändern Sie es neu, so dass jede Byte-Sequenz zulässig ist.
- Andernfalls, wenn
0x0010
nur an erster Stelle nicht erlaubt ist, immer einen konstanten Wert eingeben, gefolgt von der tatsächlichen Länge. (Zum Beispiel: 00 11 00 10 ...
)
- Andernfalls, wenn
0x0010
nicht an jeder Position erscheinen kann, entkommen sie: \x00\x10
als \\n
codiert und \
codiert wird, als \\
Schließlich 0x0010
sieht aus wie UTF-16 codiert neue Zeile. Wenn das tatsächlich so ist, sollten Sie keine Binärdaten in den Text schreiben - das wird mehr Probleme verursachen. In diesem Fall sollten Sie Ihre Zeichenfolge direkt in diesen UTF-16-codierten Text einfügen oder eine ASCII-sichere Codierung wie base64 verwenden.
Ja, 0xFF ist eines der Bytes, die in UTF-8 nicht vorhanden sein können. Und alles ≥ 0xC0 kann nicht dauern. – user2233709
'0xff' gibt'? 'Es funktioniert nicht. – Gergely
Keine Ahnung, was du meinst. Ist Ihre Frage, welchen Wert Sie für DEAD_BYTE verwenden sollten? (Ich kenne Java nicht, keine Ahnung, ob dies ein sprachdefinierter Wert ist oder etwas, das Sie selbst definiert haben.) Wenn dem so ist, denke ich, dass es Ihnen mit 0x00 gut gehen würde. Wie auch immer, die Art, wie du mit dem speziellen Wert 0x10 umgehst, sieht für mich so falsch aus ... – user2233709