¿Cómo escribir un archivo UTF-8 con Java?

180

Tengo un código actual y el problema es que está creando un archivo de página de códigos 1252, quiero forzarlo a crear un archivo UTF-8

¿Alguien puede ayudarme con este código, ya que digo que actualmente funciona ... pero necesito forzar el guardado en utf ... ¿puedo pasar un parámetro o algo?

esto es lo que tengo, cualquier ayuda realmente apreciada

var out = new java.io.FileWriter( new java.io.File( path )),
        text = new java.lang.String( src || "" );
    out.write( text, 0, text.length() );
    out.flush();
    out.close();
Mark Smith
fuente
2
Por favor, publique el código que pasa el compilador, si es posible.
JesperE
parece ser rinoceronte (javascript)
dfa

Respuestas:

208

En lugar de usar FileWriter, cree un FileOutputStream. Luego puede envolver esto en un OutputStreamWriter, que le permite pasar una codificación en el constructor. Luego puede escribir sus datos en una Declaración de prueba con recursos :

try (OutputStreamWriter writer =
             new OutputStreamWriter(new FileOutputStream(PROPERTIES_FILE), StandardCharsets.UTF_8))
    // do stuff
}
skaffman
fuente
118
... y maldice a Sun por no poner un constructor a FileWriter que toma un Charset.
Jon Skeet
3
Parece una extraña supervisión. Y todavía no lo han arreglado.
skaffman
44
@ Jon Skeet: Dado que FileWriter es un contenedor para FileOutputStream que asume la codificación predeterminada y el tamaño del búfer, ¿eso no sería un error?
Powerlord
Lo siento, me refería a OutputStreamWriter, no a FileOutputStream.
Powerlord
198

Prueba esto

Writer out = new BufferedWriter(new OutputStreamWriter(
    new FileOutputStream("outfilename"), "UTF-8"));
try {
    out.write(aString);
} finally {
    out.close();
}
Markus Lausberg
fuente
1
Creo que hay un error tipográfico. Writer out = ...debe corregirse a BufferedWriter out = ... .
asmaier
20
Writer es la clase abstracta, BufferedWriter está implementando y se declaran write () + close ().
Markus Lausberg
3
Esto crea un UTF-8 real sin BOM, no solo UTF-8. ¿Hay alguna manera de forzar eso?
NeverMind
25

Intenta usar FileUtils.writedesde Apache Commons.

Deberías poder hacer algo como:

File f = new File("output.txt"); 
FileUtils.writeStringToFile(f, document.outerHtml(), "UTF-8");

Esto creará el archivo si no existe.

A.M
fuente
44
Esto también produce un archivo UTF-8 SIN BOM ... No sé si es relevante o no.
NeverMind
3
@Smarty solo si ya está usando Apache Commons. De lo contrario, parece un desperdicio terrible incluir otro tarro solo porque no desea escribir algunos caracteres más.
Jason
No pude ver un método 'write (..)' en la clase FileUtils. Revisé los comunes IO 1.4
RRM
Si lee los documentos de Java en el enlace que se muestra en la pregunta, le indica la versión de la API de IO de Commons donde se introdujeron las API de escritura. Parece que las API de escritura se introdujeron a partir de la v2.0.
A_M
Solo me gustaría mencionar que utilicé el método FileUtils.writeStringToFile (...) (con commons-io-1.3.1.jar) en lugar de FileUtils.write (...).
Léa Massiot
21

Todas las respuestas dadas aquí no funcionarán ya que la escritura UTF-8 de Java está defectuosa.

http://tripoverit.blogspot.com/2007/04/javas-utf-8-and-unicode-writing-is.html

Emperador
fuente
Por lo que puedo decir, el error es este (ya que el autor de ese artículo no se molesta en mencionarlo): bugs.sun.com/view_bug.do?bug_id=4508058
Chris
44
El único problema al escribir es la lista de materiales que falta. No es gran cosa. Leer un archivo con una lista de materiales por otro lado requiere quitarlo manualmente.
Axel Fontaine
2
UTF-8 no necesita BOM, por lo que técnicamente el archivo escrito sigue siendo un archivo de texto codificado UTF-8 válido. El error está en leer un UTF-8 con BOM.
Kien Truong
@Chris el enlace bugs.sun.com está roto. ¿Tienes uno que funcione?
Matthias
Aún funciona para mí; No he iniciado sesión ni nada. Intenta buscar en Google el error 4508058.
Chris
21

Desde Java 7 puedes hacer lo mismo con Files.newBufferedWriterun poco más de manera sucinta:

Path logFile = Paths.get("/tmp/example.txt");
try (BufferedWriter writer = Files.newBufferedWriter(logFile, StandardCharsets.UTF_8)) {
    writer.write("Hello World!");
    // ...
}
Nigel_V_Thomas
fuente
9
var out = new java.io.PrintWriter(new java.io.File(path), "UTF-8");
text = new java.lang.String( src || "" );
out.print(text);
out.flush();
out.close();
boxofrats
fuente
6

El tipo de utilidad Java 7 Files es útil para trabajar con archivos:

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.IOException;
import java.util.*;

public class WriteReadUtf8 {
  public static void main(String[] args) throws IOException {
    List<String> lines = Arrays.asList("These", "are", "lines");

    Path textFile = Paths.get("foo.txt");
    Files.write(textFile, lines, StandardCharsets.UTF_8);

    List<String> read = Files.readAllLines(textFile, StandardCharsets.UTF_8);

    System.out.println(lines.equals(read));
  }
}

La versión de Java 8 le permite omitir el argumento Charset , los métodos predeterminados para UTF-8.

McDowell
fuente
3

podemos escribir el archivo codificado UTF-8 con java usando PrintWriter para escribir xml codificado UTF-8

O haga clic aquí

PrintWriter out1 = new PrintWriter(new File("C:\\abc.xml"), "UTF-8");
Dharmesh Patel
fuente
3

El siguiente código de muestra puede leer el archivo línea por línea y escribir un archivo nuevo en formato UTF-8. Además, estoy especificando explícitamente la codificación Cp1252.

    public static void main(String args[]) throws IOException {

    BufferedReader br = new BufferedReader(new InputStreamReader(
            new FileInputStream("c:\\filenonUTF.txt"),
            "Cp1252"));
    String line;

    Writer out = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(
                    "c:\\fileUTF.txt"), "UTF-8"));

    try {

        while ((line = br.readLine()) != null) {

            out.write(line);
            out.write("\n");

        }

    } finally {

        br.close();
        out.close();

    }
}
Estoy enojado
fuente