Sichere Codierungskonstruktoren
Es ist schwierig, Java dazu zu bringen, Sie ordnungsgemäß über Codierungsfehler zu benachrichtigen. Sie müssen den ausführlichsten und leider den am wenigsten verwendeten der vier alternativen Konstruktoren für jeden von InputStreamReader
und verwenden OutputStreamWriter
, um eine ordnungsgemäße Ausnahme für einen Codierungsfehler zu erhalten.
Stellen Sie für Datei-E / A immer sicher, dass Sie immer das zweite Argument für beide OutputStreamWriter
und InputStreamReader
das ausgefallene Encoder-Argument verwenden:
Charset.forName("UTF-8").newEncoder()
Es gibt andere, noch schickere Möglichkeiten, aber keine der drei einfacheren Möglichkeiten funktioniert für die Ausnahmebehandlung. Diese tun:
OutputStreamWriter char_output = new OutputStreamWriter(
new FileOutputStream("some_output.utf8"),
Charset.forName("UTF-8").newEncoder()
);
InputStreamReader char_input = new InputStreamReader(
new FileInputStream("some_input.utf8"),
Charset.forName("UTF-8").newDecoder()
);
Wie zum Laufen mit
$ java -Dfile.encoding=utf8 SomeTrulyRemarkablyLongcLassNameGoeShere
Das Problem ist, dass dadurch nicht das vollständige Encoder-Argument für die Zeichenströme verwendet wird und Sie erneut Codierungsprobleme verpassen.
Längeres Beispiel
Hier ist ein längeres Beispiel, das einen Prozess anstelle einer Datei verwaltet, in dem zwei verschiedene Eingabebyte-Streams und ein Ausgabebyte-Stream mit vollständiger Ausnahmebehandlung in UTF-8-Zeichenströme umgewandelt werden :
Process
slave_process = Runtime.getRuntime().exec("perl -CS script args");
OutputStream
__bytes_into_his_stdin = slave_process.getOutputStream();
OutputStreamWriter
chars_into_his_stdin = new OutputStreamWriter(
__bytes_into_his_stdin,
Charset.forName("UTF-8").newEncoder()
);
InputStream
__bytes_from_his_stdout = slave_process.getInputStream();
InputStreamReader
chars_from_his_stdout = new InputStreamReader(
__bytes_from_his_stdout,
Charset.forName("UTF-8").newDecoder()
);
InputStream
__bytes_from_his_stderr = slave_process.getErrorStream();
InputStreamReader
chars_from_his_stderr = new InputStreamReader(
__bytes_from_his_stderr,
Charset.forName("UTF-8").newDecoder()
);
Jetzt haben Sie drei Zeichenströme , dass alle raise Ausnahmefehler auf kodieren jeweils genannt chars_into_his_stdin
, chars_from_his_stdout
und chars_from_his_stderr
.
Dies ist nur geringfügig komplizierter als das, was Sie für Ihr Problem benötigen, dessen Lösung ich in der ersten Hälfte dieser Antwort gegeben habe. Der entscheidende Punkt ist, dass dies die einzige Möglichkeit ist, Codierungsfehler zu erkennen.
Lass mich nur nicht damit anfangen PrintStream
, Ausnahmen zu essen.
InputStreamReader char_input = new InputStreamWriter
sollte lauten:InputStreamReader char_input = new InputStreamReader
und derInputStreamReader
Konstruktor nimmt einCharsetDecoder
, keinCharsetEncoder
.