meist JDK Methoden einen Charset
(oder ein charset Namen) zu akzeptieren rekonfigurieren Charset(De|En)coder
fehlerhafte Eingabe und nicht zuzuordnenden Zeichen zu handhaben mit CodingErrorAction.REPLACE
:Warum verwenden die Methoden von Files CodingErrorAction.REPORT, um Codierungsfehler zu behandeln, während das gewöhnliche JDK-Verhalten REPLACE verwendet?
String
ctorsByteArrayOutputStream.toString()
InputStreamReader
ctorsOutputStreamWriter
ctorsPrintStream
ctorsPrintWriter
ctorsFormatter
ctorsScanner
ctors- usw.
Auch wenn nie in der Javadoc ausgeführt, ist es einfach, dass in OpenJDK Quellcode oder mit einfachen Testfällen zu überprüfen:
private static final byte[] INVALID_UTF_8 = new byte[] {-1, 97};
@Test
public void string_uses_replacement_characters() {
String str = new String(INVALID_UTF_8, StandardCharsets.UTF_8);
assertThat(str).isEqualTo("\uFFFDa");
}
@Test
public void inputStreamReader_uses_replacement_characters() throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(INVALID_UTF_8);
InputStreamReader isr = new InputStreamReader(bais, StandardCharsets.UTF_8);
BufferedReader br = new BufferedReader(isr);
assertThat(br.readLine()).isEqualTo("\uFFFDa");
}
Einige dieser Klassen definieren auch Methoden, die Charset(En|De)coder
für diese akzeptieren wer möchte einen anderen CodingErrorAction
angeben.
JDK 8 hinzugefügt die Files
Klasse, die Dienstprogramm/Factory-Methoden bietet, um die Boilerplate durch einige sehr häufige Aktionen erforderlich zu reduzieren. Alle diese Methoden folgen jedoch nicht dem zuvor beschriebenen üblichen Verhalten. (En | De) Codierer werden nicht neu konfiguriert, um CodingErrorAction.REPLACE
zu verwenden, und Ausnahmen werden auf ungültige Byte & nicht mappable Zeichen ausgelöst.
Kennt jemand die Vernunft dieser Änderung und warum niemand nützlich fand, es im Javadoc klar zu erklären?
Auch wenn ich denke, dass REPORT
ein serielles Standardverhalten ist, scheint es wirklich fehleranfällig, stillschweigend diese stillschweigende Vereinbarung zu ändern, die vor Jahren gemacht wurde. Die meisten Entwickler würden erwarten, dass newBuffereReader(p, "UTF-8")
zu new BufferedReader(new InputStreamReader(new FileInputStream(p), "UTF-8"))
entspricht, was nicht wahr ist.
Hinweis: https://bugs.openjdk.java.net/browse/JDK-8143997 scheint im Zusammenhang mit meiner Frage.
Dies wurde vorher nicht dokumentiert, und es ist immer noch nicht explizit dokumentiert. Ich bin mir also nicht sicher, wie wir antworten könnten, wie sich etwas, das nicht dokumentiert ist, geändert hat. Sie hätten sich nicht darauf verlassen sollen. – Tunaki
Nur der vorhandene Code muss mit älteren Versionen kompatibel bleiben. Neuer Code kann sich anders verhalten, deshalb wurde der neue Code an erster Stelle hinzugefügt. – Holger
@Tunaki: Ich weiß, dass es nicht dokumentiert wurde. Dennoch haben sich die Java-Entwickler in den letzten 10+ Jahren an das "übliche Verhalten" gewöhnt: Methoden, die behandeln, warum das Encoding codierungsbedingte Ausnahmen nicht nutzlos macht, fragen Sie. Jeder, der eine der aufgelisteten Klassen verwendet, verlässt sich auf dieses undokumentierte Verhalten. Ich finde es wirklich überraschend, dass diese Änderung in der Dokumentation nicht betont wird (sowohl in der neuen API, die den "üblichen Vertrag" bricht, als auch in der alten API, die als fehleranfällig zu gelten scheint, da REPLACE-default durch REPORT abgelöst wurde) -by-default) –