Constructores de codificación segura
Conseguir que Java le notifique correctamente los errores de codificación es complicado. Debe utilizar el más detallado y, por desgracia, el menos utilizado de los cuatro constructores alternativos para cada uno de InputStreamReader
y OutputStreamWriter
para recibir una excepción adecuada en un error de codificación.
Para la E / S de archivos, asegúrese siempre de usar siempre como segundo argumento para ambos OutputStreamWriter
y InputStreamReader
el elegante argumento del codificador:
Charset.forName("UTF-8").newEncoder()
Hay otras posibilidades aún más elegantes, pero ninguna de las tres posibilidades más simples funciona para el manejo de excepciones. Estos hacen:
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()
);
En cuanto a correr con
$ java -Dfile.encoding=utf8 SomeTrulyRemarkablyLongcLassNameGoeShere
El problema es que no utilizará la forma de argumento del codificador completo para los flujos de caracteres, por lo que volverá a perder los problemas de codificación.
Ejemplo más largo
Aquí hay un ejemplo más largo, este que administra un proceso en lugar de un archivo, donde promovemos dos flujos de bytes de entrada diferentes y un flujo de bytes de salida, todos a flujos de caracteres UTF-8 con manejo completo de excepciones :
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()
);
Ahora tiene tres corrientes de carácter que toda excepción aumento en la codificación de errores, llamados respectivamente chars_into_his_stdin
, chars_from_his_stdout
y chars_from_his_stderr
.
Esto es solo un poco más complicado de lo que necesita para su problema, cuya solución di en la primera mitad de esta respuesta. El punto clave es que esta es la única forma de detectar errores de codificación.
No me hagas hablar de PrintStream
las excepciones alimenticias.
InputStreamReader char_input = new InputStreamWriter
debería leer:,InputStreamReader char_input = new InputStreamReader
y elInputStreamReader
constructor toma unCharsetDecoder
, no unCharsetEncoder
.