如何在Java中以UTF-8格式读写文件?

17
我遇到了这个错误:

io.MalformedByteSequenceException: 2 字节 UTF-8 序列的第 2 个字节无效

解决方法是以 UTF-8 格式读写文件。
我的代码是:
InputStream input = null;
OutputStream output = null;
OutputStreamWriter bufferedWriter = new OutputStreamWriter( output, "UTF8");
input = new URL(url).openStream();
output = new FileOutputStream("DirectionResponse.xml");
byte[] buffer = new byte[1024];
for (int length = 0; (length = input.read(buffer)) > 0;) {
   output.write(buffer, 0, length);
}
BufferedReader br = new BufferedReader(new FileReader("DirectionResponse.xml" ));
FileWriter fstream = new FileWriter("ppre_DirectionResponse.xml");
BufferedWriter out = new BufferedWriter(fstream);

我正在读取一个URL并将其写入文件DirectionResponse.xml。然后读取DirectionResponse.xml并将其写入ppre_DirecionResponse.xml以进行处理。

我该如何更改此设置,以便使用UTF-8进行读写操作?

2个回答

39

首先,在重新打开文件进行输入操作之前,您需要调用output.close()(或至少调用output.flush())。那可能是您问题的主要原因。

然后,您不应该使用FileReaderFileWriter,因为它总是使用平台默认编码(通常不是UTF-8)。来自FileReader文档

此类的构造函数假定默认字符编码和默认字节缓冲区大小适合。

在使用FileWriter时也会遇到相同的问题。将这个替换掉:

BufferedReader br = new BufferedReader(new FileReader("DirectionResponse.xml" ));

就像这样:

BufferedReader br = new BufferedReader(new InputStreamReader(
    new FileInputStream("DirectionResponse.xml"), "UTF-8"));

对于fstream也是同样的。


1
@Aubin - 当然可以,至少如果你是在谈论输入流的话:URLConnection conn = url.openConnection(); InputStream is = conn.getInputStream();。然后使用 is 作为输入流。 - Ted Hopp
@user905911 - 我注意到你的代码还有另一个问题。请查看我修改后答案的第一段。 - Ted Hopp
@TedHopp:先生,它起作用了。但我不知道如何更改FileWriter。我应该改成OutputStreamWriter吗? - Gaurav Wadhwani
好的,我将其更改为 FileOutputStream fos = new FileOutputStream("ppre_DirectionResponse.xml"); Writer out = new OutputStreamWriter(fos, "UTF8"); - Gaurav Wadhwani
自Java 7以来,可以使用更短的方式完成:BufferedReader br = Files.newBufferedReader(Paths.get("DirectionResponse.xml"), StandardCharsets.UTF_8); - Vladimir Vagaytsev

2

Java中读写UTF-8文件

我看到你正在使用utf-8编写,但没有明确地以utf-8读取。请按照我提供的链接示例进行操作。

try {
   Reader reader =
      new InputStreamReader(
         new FileInputStream(args[0]),"UTF-8");
   BufferedReader fin = new BufferedReader(reader);
   Writer writer =
      new OutputStreamWriter(
         new FileOutputStream(args[1]), "UTF-8");
   BufferedWriter fout = new BufferedWriter(writer);
   String s;
   while ((s=fin.readLine())!=null) {
      fout.write(s);
      fout.newLine();
   }

            //Remember to call close. 
            //calling close on a BufferedReader/BufferedWriter 
            // will automatically call close on its underlying stream 
   fin.close();
   fout.close();
} catch (IOException e) {
   e.printStackTrace();
}

我看过那个,但问题是我需要读取一个URL,这些函数不能读取URL。 - Gaurav Wadhwani
@user905911,您在问题中没有指定这一点。 - Aravind Yarram
1
fin.close();fout.close(); 必须在 finally 块中调用。自 Java 7 开始,最好使用 try-with-resources 方法。 - Vladimir Vagaytsev

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