[Java] UTF-8 (mit Stückliste) wird in 0xFFFD (REPLACEMENT CHARACTER) konvertiert.

Einführung

Bei der Systemänderung (Java 7) habe ich einen Prozess erstellt, um die Anzahl der Zeilen zu zählen, deren erstes Zeichen "K" in der von FTP empfangenen Datei ist. Der reguläre Ausdruck "^ K. *" wird verwendet, um zu bestimmen, ob das erste Zeichen der Zeile "K" ist.

Im Test wurde die empfangene Datei als Shift-JIS erstellt, sodass es kein Problem gab, den Zeichencode zum Lesen der empfangenen FTP-Datei mit "Windows 31J" anzugeben. Die tatsächlich empfangene FTP-Datei ist jedoch UTF-8 (mit Stückliste). Daher hat die Stückliste "K" nicht nur für die erste Zeile bestimmt, und die Gesamtzahl der Zeilen stimmte nicht überein.

Es war ein Versehen der Spezifikationen.

BOM Was ist Stückliste? "Byte Order Mark (https://ja.wikipedia.org/wiki/%E3%83%90%E3%82%A4%E3%83%88%E3%82%AA" % E3% 83% BC% E3% 83% 80% E3% 83% BC% E3% 83% 9E% E3% 83% BC% E3% 82% AF)) "," Diese Datei ist im Unicode-Format. Es sind die Informationen, die unterscheiden, dass sie geschrieben sind.

Es werden nur die Hauptzeichencodes und die Stückliste extrahiert.

Zeichencode Endian Unterscheidung Stücklistencode
UTF-8 0xEF 0xBB 0xBF
UTF-16 BE 0xFE 0xFF
LE 0xFF 0xFE

Stückliste überspringen

Ich habe einen Prozess zum Überspringen der Stückliste hinzugefügt, indem ich auf den Code auf der folgenden Site verwiesen habe, aber das Ergebnis ändert sich nicht. [JAVA] Manuelle Entfernungslogik der Stückliste (Byte Of Mark)

private static String excludeBOMString(String original_str) {
	if (original_str != null) {
		char c = original_str.charAt(0);
		if (Integer.toHexString(c).equals("feff")) {
			StringBuilder sb = new StringBuilder();
			for (int i=1; i < original_str.length(); i++) {
				sb.append(original_str.charAt(i));
			}
			return sb.toString();
		} else {
			return original_str;
		}
	} else {
		return "";
	}
}

Warum? Als ich es auf Windows 7 Eclipse meines PCs debuggte, war das erste Zeichen "fffd". Als ich den Zeichencode etwas genauer nachgeschlagen habe, war es wie folgt und ich fand, dass ich 3 Zeichen zum ersten Zeichen "K (0x4b)" überspringen sollte. Es ist ein UTF-8-Stücklistencode (0xEF, 0xBB, 0xBF), und obwohl ich denke, dass der interne Java-Code UTF-16LE ist, der sich vom Stücklistencode (0xfeff) unterscheidet, hatte ich bis zur Nachmittagsüberprüfung keine Zeit, daher habe ich ihn vorerst geklärt. Ich habe es aufgeschoben.

Index Zeichencode
0 0xfffd
1 0xff7b
2 0xff7f
3 0x4b

Das Stücklistenurteil wurde auf "fffd" gesetzt und das Überspringen auf 3 Zeichen korrigiert. Jetzt können Sie die Stückliste normal überspringen und die Gesamtzahl der Zeilen mit "K" als erstem Zeichen abrufen.

private static String excludeBOMString(String original_str) {
	if (original_str != null) {
		char c = original_str.charAt(0);
		if (Integer.toHexString(c).equals("fffd")) {
			StringBuilder sb = new StringBuilder();
			for (int i=3; i < original_str.length(); i++) {
				sb.append(original_str.charAt(i));
			}
			return sb.toString();
		} else {
			return original_str;
		}
	} else {
		return "";
	}
}

Bei der Nachmittagsüberprüfung habe ich die geänderten Programme ersetzt, aber die Gesamtzahl stimmte nicht überein. Warum? Wenn ich dachte, ich würde es auf Windows 7 Eclipse meines PCs debuggen, würde die Gesamtzahl übereinstimmen. Da es sich bei der Überprüfungsumgebung um Windows Server 2012 R2 handelt, wurde beim Versuch, die Lesezeile durch Debuggen auszugeben, um festzustellen, ob sich je nach Umgebung etwas unterscheidet, das Zeichen nach "K" angezeigt. Wenn Sie also den Sprung von 3 Zeichen auf 2 Zeichen ändern, wird die Gesamtzahl geändert Kam zu passen.

Es ist jedoch beängstigend, dass es von der Umgebung abhängt.

0xFFFD(REPLACEMENT CHARACTER) Wie auch immer, die Überprüfungsarbeiten am Nachmittag waren beendet, und ich beschloss, die Ursache zu untersuchen.

Wenn Sie in Bezug auf "0xfffd" versuchen, eine in UTF-8 mit Shift-JIS codierte Textdatei zu lesen, wird das entsprechende Zeichen in das Zeichen "0xFFFD" konvertiert, wenn es nicht vorhanden ist. Informationen zur Erkennung verstümmelter Zeichen in Java

In meiner Umgebung (Windows 7) ... Codenummer 0xFFFD "ERSATZZEICHEN", Herr �! In meiner Umgebung handelt es sich um einen schwarzen Diamanten mit einem weißen "?" - Zeichen. Wird er also nicht richtig angezeigt? Ich dachte, aber dies scheint "Zeichen zu sein, die angezeigt werden sollen, wenn sie nicht angezeigt werden können", also scheint dies in Ordnung zu sein Das größte Zeichen in Unicode

Da der Zeichencode zum Lesen der Datei als "Windows 31J" angegeben wurde, bedeutet dies, dass der Stücklistencodeteil in das Zeichen "0xfffd" konvertiert wird, sofern das entsprechende Zeichen nicht vorhanden ist. Davon war ich überzeugt.

In Bezug auf den Fall, dass die Anzahl der Sprungzeichen unter Windows 7 und Windows Server 2012 R2 unterschiedlich war, war das zweite "0xff7b" unter Windows Server 2012 R2 verschwunden, sodass sich herausstellte, dass das Überspringen von 3 Zeichen zu weit gehen würde.

Index Gewinnen Sie einen 7-Zeichen-Code Index Win2012 Zeichencode
0 0xfffd 0 0xfffd
1 0xff7b
2 0xff7f 1 0xff7f
3 0x4b 2 0x4b

Ich habe online gesucht, aber keine Literatur dazu gefunden. Da die Zeichen in der Datei nur alphanumerische Zeichen sind, anstatt Zeit für diese Untersuchung aufzuwenden, entschied ich, dass es besser ist, den Zeichencode zum Lesen der Datei als "UTF-8" anzugeben, und änderte das Programm. ..

Infolgedessen lautete die Beurteilung des Stücklistencodes "0xfeff" und der Sprung bestand aus einem Zeichen, wobei die ursprüngliche manuelle Entfernungslogik beibehalten wurde. Wir haben es unter Windows 7 und Windows Server 2012 R2 getestet und beide haben die gleichen Ergebnisse erzielt.

Schließlich

Dieses Mal war es meine erste Erfahrung, in REPLACEMENT CHARACTER (0xfffd) konvertiert zu werden, also schrieb ich es als Memorandum.

Wenn wir über UTF-8 in Java sprechen, gehen wir von UTF-8 ohne Stückliste aus, und obwohl es verschiedene Diskussionen gibt, scheinen wir aufgrund von Abwärtskompatibilitätsproblemen nicht beabsichtigen, uns damit zu befassen. Siehe auch: [Was passiert, wenn ich eine UTF8-Datei mit Java SE BOM lese? ](Https://hondou.homedns.org/pukiwiki/pukiwiki.php?JavaSE%20BOM%C9%D5%A4%ADUTF8%A5%D5%A5%A1%A5%A4%A5%EB%A4%F2% C6% C9% A4% DF% B9% FE% A4% E0% A4% C8% A4% C9% A4% A6% A4% CA% A4% EB% A4% AB% A1% A9)

Ich habe zuvor PHP mit Stückliste verwendet, aber mit / ohne Stückliste ist umständlich.

Recommended Posts

[Java] UTF-8 (mit Stückliste) wird in 0xFFFD (REPLACEMENT CHARACTER) konvertiert.
So löschen Sie Stücklisten (UTF-8)
Java zum Spielen mit Function
Stellen Sie mit Java eine Verbindung zur Datenbank her
Stellen Sie mit Java eine Verbindung zu MySQL 8 her
Ist es möglich, Getter / Setter automatisch mit Java Interface zu generieren?
Projektfacette Java Version 13 wird nicht unterstützt. Wie man damit umgeht
Java mit Ramen lernen [Teil 1]
Wie man ein Zeichen mit "~" einschließt
Wagen Sie es, Kaggle mit Java herauszufordern (1)
Ich habe versucht, mit Java zu interagieren
So kompilieren Sie Java mit VsCode & Ant
[Java] Fassen Sie zusammen, wie Sie mit der Methode equals vergleichen können
[Java] Map # Merge ist schwer zu verstehen.
3 schwierige Punkte für Java Realm
[Java] Vorsichtsmaßnahmen beim Vergleichen von Zeichenfolgen mit Zeichenfolgen
Einfach mit regulären Java-Ausdrücken zu stolpern
Einführung in Algorithmen mit Java --Search (Breitenprioritätssuche)
Initialisieren Sie das Ruby-Array mit 0 für Java, dh setzen Sie den Standardwert auf 0