¿Escribir un archivo en UTF-8 usando FileWriter (Java)?

Sin embargo, tengo el siguiente código, quiero que escriba como un archivo UTF-8 para manejar caracteres extraños. ¿Hay alguna forma de hacerlo? ¿Hay alguna necesidad de tener un parámetro?

Realmente apreciaría tu ayuda con esto. Gracias.

try { BufferedReader reader = new BufferedReader(new FileReader("C:/Users/Jess/My Documents/actresses.list")); writer = new BufferedWriter(new FileWriter("C:/Users/Jess/My Documents/actressesFormatted.csv")); while( (line = reader.readLine()) != null) { //If the line starts with a tab then we just want to add a movie //using the current actor's name. if(line.length() == 0) continue; else if(line.charAt(0) == '\t') { readMovieLine2(0, line, surname.toString(), forename.toString()); } //Else we've reached a new actor else { readActorName(line); } } } catch (IOException e) { e.printStackTrace(); } 

Constructores de encoding segura

Hacer que Java le notifique correctamente sobre los errores de encoding es complicado. Debe usar el más detallado y, por desgracia, el menos utilizado de los cuatro contructores alternativos para cada uno de InputStreamReader y OutputStreamWriter para recibir una excepción adecuada en un error de encoding.

Para la E / S de archivos, siempre asegúrese de utilizar siempre como segundo argumento tanto OutputStreamWriter como InputStreamReader el argumento del codificador de fantasía:

  Charset.forName("UTF-8").newEncoder() 

Hay otras posibilidades aún más sofisticadas, pero ninguna de las tres posibilidades más simples funciona para la entrega 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 eso no usará el formato de argumento del codificador completo para las transmisiones de caracteres, por lo que perderá nuevamente los problemas de encoding.

Ejemplo más largo

Aquí hay un ejemplo más largo, este administrando 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 de excepciones completo :

  // this runs a perl script with UTF-8 STD{IN,OUT,ERR} streams Process slave_process = Runtime.getRuntime().exec("perl -CS script args"); // fetch his stdin byte stream... OutputStream __bytes_into_his_stdin = slave_process.getOutputStream(); // and make a character stream with exceptions on encoding errors OutputStreamWriter chars_into_his_stdin = new OutputStreamWriter( __bytes_into_his_stdin, /* DO NOT OMIT! */ Charset.forName("UTF-8").newEncoder() ); // fetch his stdout byte stream... InputStream __bytes_from_his_stdout = slave_process.getInputStream(); // and make a character stream with exceptions on encoding errors InputStreamReader chars_from_his_stdout = new InputStreamReader( __bytes_from_his_stdout, /* DO NOT OMIT! */ Charset.forName("UTF-8").newDecoder() ); // fetch his stderr byte stream... InputStream __bytes_from_his_stderr = slave_process.getErrorStream(); // and make a character stream with exceptions on encoding errors InputStreamReader chars_from_his_stderr = new InputStreamReader( __bytes_from_his_stderr, /* DO NOT OMIT! */ Charset.forName("UTF-8").newDecoder() ); 

Ahora tiene tres secuencias de caracteres que chars_into_his_stdin excepciones en los errores de encoding, llamados chars_into_his_stdin , chars_from_his_stdout y chars_from_his_stderr .

Esto es solo un poco más complicado que 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 encoding.

Simplemente no me PrintStream las excepciones de alimentación de PrintStream .

Ditch FileWriter y FileReader , que son inútiles porque no permiten especificar la encoding. En cambio, usa

new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8)

y

new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);

Necesita usar la clase OutputStreamWriter como parámetro de BufferedWriter para su BufferedWriter . Acepta una encoding. Revise javadocs por ello.

Algo como esto:

 BufferedWriter out = new BufferedWriter(new OutputStreamWriter( new FileOutputStream("jedis.txt"), "UTF-8" )); 

O puede configurar la encoding del sistema actual con la propiedad del sistema file.encoding a UTF-8.

 java -Dfile.encoding=UTF-8 com.jediacademy.Runner arg1 arg2 ... 

También puede establecerlo como una propiedad del sistema en tiempo de ejecución con System.setProperty(...) si solo lo necesita para este archivo específico, pero en un caso como este creo que preferiría el OutputStreamWriter .

Al establecer la propiedad del sistema, puede usar FileWriter y esperar que use UTF-8 como la encoding predeterminada para sus archivos. En este caso, para todos los archivos que lee y escribe.

EDITAR

  • A partir de API 19, puede reemplazar la cadena “UTF-8” con StandardCharsets.UTF_8

  • Como se sugiere en los comentarios más abajo por tchrist , si tiene la intención de detectar errores de encoding en su archivo, se verá obligado a utilizar el enfoque OutputStreamWriter y utilizar el constructor que recibe un codificador de conjunto de caracteres.

    Algo así como

     CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder(); encoder.onMalformedInput(CodingErrorAction.REPORT); encoder.onUnmappableCharacter(CodingErrorAction.REPORT); BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("jedis.txt"),encoder)); 

    Puedes elegir entre acciones IGNORE | REPLACE | REPORT IGNORE | REPLACE | REPORT

Además, esta pregunta ya fue respondida aquí .

Con el texto en chino, traté de usar el Charset UTF-16 y afortunadamente funcionó.

Espero que esto pueda ayudar!

 PrintWriter out = new PrintWriter( file, "UTF-16" ); 

Desde Java 7, existe una manera fácil de manejar la encoding de caracteres de BufferedWriter y BufferedReaders. Puede crear un BufferedWriter directamente utilizando la clase Files en lugar de crear varias instancias de Writer. Simplemente puede crear un BufferedWriter, que considera la encoding de caracteres, llamando al:

 Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8); 

Puede encontrar más sobre esto en JavaDoc:

  • Clase de archivos
  • Archivos # newBufferedWriter

en mi opinión

Si quieres escribir follow tipo UTF-8 . Debes crear una matriz de bytes. Luego, puedes hacer lo siguiente: byte[] by=("< ?xml version=\"1.0\" encoding=\"utf-8\"?>"+"Your string".getBytes();

Luego, puede escribir cada byte en el archivo que creó. Ejemplo:

 OutputStream f=new FileOutputStream(xmlfile); byte[] by=("< ?xml version=\"1.0\" encoding=\"utf-8\"?>"+"Your string".getBytes(); for (int i=0;i