如何使用Java编写UTF-8文件?

198

我有一些现有的代码,问题在于它创建了一个1252的代码页文件,我想强制它创建一个UTF-8文件

有谁可以帮我修改这段代码吗?目前它能正常工作...但是我需要强制保存为utf。我该传递参数或其他什么吗?

这是我目前的代码,请帮忙,非常感谢。

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();

2
请尽可能发布通过编译器的代码。 - JesperE
它看起来像是Rhino(JavaScript)。 - dfa
10个回答

226

不要使用FileWriter,而是创建一个FileOutputStream。然后你可以将其包装在一个OutputStreamWriter中,在构造函数中传递编码。然后你可以在try-with-resources语句内将数据写入其中:

try (OutputStreamWriter writer =
             new OutputStreamWriter(new FileOutputStream(PROPERTIES_FILE), StandardCharsets.UTF_8))
    // do stuff
}

133
并且咒骂Sun没有在FileWriter中添加一个接受Charset的构造函数。 - Jon Skeet
4
这似乎是一个奇怪的疏忽,而且他们仍然没有修复它。 - skaffman
4
鉴于FileWriter是FileOutputStream的包装器,它假设默认编码和缓冲区大小,那么这不会有违初衷吗? - Powerlord
抱歉,我是指OutputStreamWriter,而不是FileOutputStream。 - Powerlord
我建议将实现Closeable接口的每个类型的声明分开,特别是如果您使用try with resources,例如“new FileOutputStream”;这是一个好习惯,可以避免未来出现“IOException:打开文件太多”的错误。 - Luis Carlos

209

试试这个

Writer out = new BufferedWriter(new OutputStreamWriter(
    new FileOutputStream("outfilename"), "UTF-8"));
try {
    out.write(aString);
} finally {
    out.close();
}

1
我认为这里有个打字错误。 Writer out = ... 应该更正为 BufferedWriter out = ... - asmaier
20
写作者是一个抽象类,BufferedWriter是它的实现类,write()和close()方法在其中被声明。 - Markus Lausberg
3
可以强制生成没有BOM的UTF-8,而不仅仅是普通的UTF-8。有没有方法可以实现这一点? - neverMind

32
尝试使用Apache Commons中的FileUtils.write。您应该能够执行以下操作:
File f = new File("output.txt"); 
FileUtils.writeStringToFile(f, document.outerHtml(), "UTF-8");

如果文件不存在,这将创建该文件。


5
这同样会生成一个没有BOM的UTF-8文件...我不知道它是否相关。 - neverMind
3
只有当你已经在使用Apache Commons时,@Smarty 才适用。否则,为了避免写更多的字符而另外引入一个jar文件似乎是非常浪费的。 - Jason
我在FileUtils类中找不到'write(..)'方法。 我已经检查了commons IO 1.4。 - RRM
如果您阅读问题中显示的Java文档,它会告诉您Commons IO API的版本,其中包含了写入API。看起来写入API是从v2.0开始引入的。 - A_M
我想提一下,我使用了方法FileUtils.writeStringToFile(...)(使用commons-io-1.3.1.jar),而不是FileUtils.write(...)。 - Léa Massiot
这是最好的答案。例如,如果您想使用不同编码(例如ISO-8859-15)从文件中读取内容,则可以使用FileUtils.readFileToString(input,“ISO-8859-15”)以该编码读取文件,并使用FileUtils.writeStringToFile将其转换为UTF8。 - Jesus

23

自Java 7以来,您可以使用Files.newBufferedWriter更简洁地完成相同的操作:

Path logFile = Paths.get("/tmp/example.txt");
try (BufferedWriter writer = Files.newBufferedWriter(logFile, StandardCharsets.UTF_8)) {
    writer.write("Hello World!");
    // ...
}

20

据我所知,这个 bug 就是这个(因为那篇文章的作者没有提到它):http://bugs.sun.com/view_bug.do?bug_id=4508058 - Chris
4
写作时唯一的问题是缺少字节顺序标记(BOM),这并不重要。然而,读取带有 BOM 的文件需要手动剥离它。 - Axel Fontaine
2
UTF-8不需要BOM,因此从技术上讲,编写的文件仍然是一个有效的UTF-8编码的文本文件。问题在于读取带有BOM的UTF-8文件。 - Kien Truong
1
@Chris,bugs.sun.com的链接已失效,你有其他可行的链接吗? - Matthias
对我来说仍然有效;我没有登录或做任何事情。尝试在Google上搜索错误4508058。 - Chris

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();

9
Java NIO
作为Java NIO的一部分,Java 7的Files实用工具类型非常适用于文件操作:
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));
  }
}

Java 8版本允许您省略Charset参数-方法默认为UTF-8。
Files.write(textFile, lines);

4
我们可以使用java编写UTF-8编码的文件,使用PrintWriter来编写UTF-8编码的xml文件。
或者点击这里
PrintWriter out1 = new PrintWriter(new File("C:\\abc.xml"), "UTF-8");

4

以下示例代码可以逐行读取文件并以UTF-8格式编写新文件。此外,我明确指定了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();

    }
}

1
简单、高效、可行。 - Bastien Gallienne

0

这是一个关于在Eclipse IDE和文件中编写UTF-8字符的示例。

对于Eclipse,只需从运行 -> 运行配置 -> 公共设置编码为UTF-8即可。 公共对话框

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class UTF_8_Example {

    /**
     * Example of printing UTF-8 characters inside Eclipse IDE and a File.
     * <p>
     * For eclipse, you must go to Run ->  Run Configurations -> Common 
     * and set Encoding to UTF-8.
     * <p>
     * @param args
     */
    public static void main(String[] args) {
        BufferedWriter writer = null;

        try {
            ///////////////////////////////////////////////////////////////////
            // WRITE UTF-8 WITHIN ECLIPSE EDITOR
            ///////////////////////////////////////////////////////////////////         
            char character = '►';
            int code = character;
            char hex = '\u25ba';
            String value = "[" + Integer.toHexString(code) + "][\u25ba][" + character + "][" + (char)code + "][" + hex + "]";
            System.out.println(value);

            ///////////////////////////////////////////////////////////////////
            // WRITE UTF-8 TO A FILE
            ///////////////////////////////////////////////////////////////////
            File file = new File("UTF_8_EXAMPLE.TXT");
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8");
            writer = new BufferedWriter(outputStreamWriter);
            writer.write(value);
        }
        catch(Throwable e) {
            throw new RuntimeException(e);
        }
        finally {
            try {
                if(writer != null) { writer.close(); }
            }
            catch(Throwable e) {
                throw new RuntimeException(e);              
            }
        }
    }   
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接