Java:如何将文件转换为UTF-8

13

我有一个文件,其中包含一些非UTF8字符(例如“ISO-8859-1”),因此我想将该文件转换(或读取)为UTF8编码,我该如何做?

代码如下:

File file = new File("some_file_with_non_utf8_characters.txt");

/* some code to convert the file to an utf8 file */

...

编辑:添加一个编码示例


非UTF8编码?想缩小范围吗?如果你知道输入编码,那么这很容易解决,如果你不知道,那几乎是不可能的。 - Matthew Flaschen
一些注意事项,这些文件很大(像1GB),所以我不能将它们放入String对象中... - Enrique San Martín
你的文件使用的是什么编码?如果你在Linux或OS X(以及其他类Unix系统)上,只需输入命令:file some_file,它就会告诉你文件的编码。顺便说一句,如果你在Unix上(至少在Linux和OS X上),你应该有iconv命令行。*"man iconv"*说:“将给定文件的编码从一种编码转换为另一种编码”,这可能比自己编写的Java工具在处理1GB文件时更好。请注意,UTF-8编码可以表示每个Unicode代码点,因此说文件“有一些非UTF-8字符”听起来有些可疑... - NoozNooz42
@NoozNooz42:该应用程序将在win32和unix/linux中运行。 - Enrique San Martín
4个回答

19

以下代码将文件从srcEncoding转换为tgtEncoding:

public static void transform(File source, String srcEncoding, File target, String tgtEncoding) throws IOException {
    BufferedReader br = null;
    BufferedWriter bw = null;
    try{
        br = new BufferedReader(new InputStreamReader(new FileInputStream(source),srcEncoding));
        bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(target), tgtEncoding));
        char[] buffer = new char[16384];
        int read;
        while ((read = br.read(buffer)) != -1)
            bw.write(buffer, 0, read);
    } finally {
        try {
            if (br != null)
                br.close();
        } finally {
            if (bw != null)
                bw.close();
        }
    }
}

--编辑--

使用Try-with-resources(Java 7):

public static void transform(File source, String srcEncoding, File target, String tgtEncoding) throws IOException {
    try (
      BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(source), srcEncoding));
      BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(target), tgtEncoding)); ) {
          char[] buffer = new char[16384];
          int read;
          while ((read = br.read(buffer)) != -1)
              bw.write(buffer, 0, read);
    } 
}

2
忽略我的评论,你是对的。顺便说一句,在finally中没有见过这种关闭方式。聪明。 - BalusC

12
  String charset = "ISO-8859-1"; // or what corresponds
  BufferedReader in = new BufferedReader( 
      new InputStreamReader (new FileInputStream(file), charset));
  String line;
  while( (line = in.readLine()) != null) { 
    ....
  }

这里有文本的解码结果。使用对称的Writer/OutputStream方法,您可以选择自己喜欢的编码(例如UTF-8)进行编写。


按行读取的潜在问题在于您可能会更改行尾/分隔符。例如,如果最后一行没有行结束符,则会添加一个。 - Stephen C
这是完全正确的。同样,经常情况下这种效果实际上是可取的(更像是“打磨”而不是“改变”)。但是,是的,人们必须意识到这一点。 - leonbloy
嗨,如果我不知道源/输入编码格式怎么办?你能否请给予一些指导。 - Alekhya Vemavarapu

5

您需要知道输入文件的编码方式。例如,如果文件是Latin-1编码,您可以这样操作:

        FileInputStream fis = new FileInputStream("test.in");
        InputStreamReader isr = new InputStreamReader(fis, "ISO-8859-1");
        Reader in = new BufferedReader(isr);
        FileOutputStream fos = new FileOutputStream("test.out");
        OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
        Writer out = new BufferedWriter(osw);

        int ch;
        while ((ch = in.read()) > -1) {
            out.write(ch);
        }

        out.close();
        in.close();

2
简述:以文件本身的编码方式读取,然后以新的编码方式写入 - BalusC

1
你只想以UTF-8格式读取它吗? 最近我遇到了类似的问题,我的解决方法是使用-Dfile.encoding=UTF-8启动JVM,并像平常一样进行读取/打印。我不知道这是否适用于你的情况。
有了这个选项:
System.out.println("á é í ó ú")

正确打印字符。否则会打印一个问号符号。


@McD:我本来也要发同样的评论。这是对-Dfile.encoding使用的误解。 - BalusC

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