1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > java写入文件中文乱码问题_解决Java写入UTF-8文件中文乱码问题

java写入文件中文乱码问题_解决Java写入UTF-8文件中文乱码问题

时间:2023-02-04 15:33:46

相关推荐

java写入文件中文乱码问题_解决Java写入UTF-8文件中文乱码问题

最近需要从Java中输出UTF-8编码的XML文件,遇到了两次中文乱码问题。一是奇数个汉字出现乱码,二是写入文件的实际编码与XML声明的编码不符。经过几番折腾,终于解决这两个问题,也对Java的字符编码加深了了解。

问题重现

以下面XML为例:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<test>一一一</test>

1

2

<?xmlversion="1.0"encoding="UTF-8"standalone="no"?>

<test>一一一</test>

生成XML代码如下:

Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();

Element elem = doc.createElement("test");

elem.setTextContent("一一一");

doc.appendChild(elem);

DOMSource source = new DOMSource(doc);

ByteArrayOutputStream bytes = new ByteArrayOutputStream();

Transformer transformer = TransformerFactory.newInstance().newTransformer();

StreamResult result = new StreamResult(bytes);

Properties properties = transformer.getOutputProperties();

properties.setProperty(OutputKeys.INDENT, "yes");

properties.setProperty(OutputKeys.ENCODING, "UTF-8");

properties.setProperty("{/xslt}indent-amount", "2");

transformer.setOutputProperties(properties);

transformer.transform(source, result);

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

Documentdoc=DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();

Elementelem=doc.createElement("test");

elem.setTextContent("一一一");

doc.appendChild(elem);

DOMSourcesource=newDOMSource(doc);

ByteArrayOutputStreambytes=newByteArrayOutputStream();

Transformertransformer=TransformerFactory.newInstance().newTransformer();

StreamResultresult=newStreamResult(bytes);

Propertiesproperties=transformer.getOutputProperties();

properties.setProperty(OutputKeys.INDENT,"yes");

properties.setProperty(OutputKeys.ENCODING,"UTF-8");

properties.setProperty("{/xslt}indent-amount","2");

transformer.setOutputProperties(properties);

transformer.transform(source,result);

至此,XML已存储至bytes中。

接下来我想XML保存至文件,想当然地写了以下代码:

String xmlStr = bytes.toString();

FileWriter writer = new FileWriter("test.xml");

writer.write(xmlStr);

writer.close();

1

2

3

4

5

StringxmlStr=bytes.toString();

FileWriterwriter=newFileWriter("test.xml");

writer.write(xmlStr);

writer.close();

不料得到的XML文件中文部分出现乱码,且XML标签的一个字符'

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<test>丿؀丿/test>

1

2

<?xmlversion="1.0"encoding="UTF-8"standalone="no"?>

<test>丿؀丿/test>

该问题只出现在中文字符为奇数个时,原因见参考链接1。

经过一番修改,写出如下代码:

String xmlStr = bytes.toString("UTF-8");

FileWriter writer = new FileWriter("test.xml");

writer.write(xmlStr);

writer.close();

1

2

3

4

5

StringxmlStr=bytes.toString("UTF-8");

FileWriterwriter=newFileWriter("test.xml");

writer.write(xmlStr);

writer.close();

得到另一种乱码:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<test>һһһ</test>

1

2

<?xmlversion="1.0"encoding="UTF-8"standalone="no"?>

<test>һһһ</test>

经观察,该文件实际为GB编码,因Notepad++根据XML的encoding属性自动识别并显示为UTF-8造成乱码,将该文件以GB编码显示正常。

搜索得到原因,Java的FileWriter以平台默认编码写入文件。于是修改代码如下:

String xmlStr = bytes.toString("UTF-8");

FileOutputStream fos = new FileOutputStream("test.xml");

OutputStreamWriter writer = new OutputStreamWriter(fos, "UTF-8");

writer.write(xmlStr);

writer.close();

1

2

3

4

5

StringxmlStr=bytes.toString("UTF-8");

FileOutputStreamfos=newFileOutputStream("test.xml");

OutputStreamWriterwriter=newOutputStreamWriter(fos,"UTF-8");

writer.write(xmlStr);

writer.close();

String xmlStr = bytes.toString("UTF-8");

FileOutputStream fos = new FileOutputStream("test.xml");

fos.write(bytes.toByteArray());

fos.close();

1

2

3

4

5

StringxmlStr=bytes.toString("UTF-8");

FileOutputStreamfos=newFileOutputStream("test.xml");

fos.write(bytes.toByteArray());

fos.close();

至此得到无乱码的XML文件。

问题分析

Transformer得到的bytes为UTF-8的二进制数据,若使用toString()会使用系统默认编码对此数据进行编码并转为字符串(Unicode存储),造成奇数个汉字乱码问题。使用toString(“UTF-8”)指定编码格式即可解决此问题。

使用FileWriter将字符串写入文件时仍会将字符串(Unicode存储)转换为系统默认编码写入文件,这就造成文件实际编码格式与XML中声明的编码格式不同。使用OutputStreamWriter指定编码格式,或者将UTF-8的二进制数据用FileOutputStream直接写入文件,即可解决此问题。

参考链接

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。