最近需要从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("{http://xml.apache.org/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("{http://xml.apache.org/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直接写入文件,即可解决此问题。

参考链接

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

  1. java 中文问号问题_解决java中的中文乱码问题(ZT)

    一般在传送时使用的encoding:使用GET 的方式: String test = new String((request.getParameter("test")).getBy ...

  2. python2中文输出代码_解决vscode python print 输出窗口中文乱码的问题

    解决vscode python print 输出窗口中文乱码的问题 发布时间:2020-09-17 23:53:25 来源:脚本之家 阅读:119 一.搭建 python 环境 在 VSC 中点击 F ...

  3. python mysql驱动写入datetime类型的数据_解决python写入mysql中datetime类型遇到的问题...

    刚开始使用python,还不太熟练,遇到一个datetime数据类型的问题: 在mysql数据库中,有一个datetime类型的字段用于存储记录的日期时间值.python程序中有对应的一个dateti ...

  4. python中文字体下载_解决Linux系统下python matplotlib中文字体显示问题

    最近想学习一些python数据分析的内容,就弄了个爬虫爬取了一些数据,并打算用Anaconda一套的工具(pandas, numpy, scipy, matplotlib, jupyter)等进行一些 ...

  5. python有中文无法保存_解决python3爬虫无法显示中文的问题

    解决python3爬虫无法显示中文的问题 有时候使用python从网站上爬数据的时候,如果数据里包含中文,有时候显示的却是如下所示...\xe4\xba\xba\xef\xbc\x8c\xe6...类 ...

  6. mysql java中文乱码_解决JAVA写mysql时出现中文乱码的现象

    参考地址:http://www.cnblogs.com/amboyna/archive/2008/06/18/1224570.html 今天部署已有一个java服务到另一台机器时出现写入数据库中文乱码 ...

  7. java 插入 mysql 乱码_解决java中插入mysql中文乱码的方法

    解决java中插入mysql中文乱码的方法 发布时间:2020-07-11 14:35:11 来源:亿速云 阅读:100 作者:清晨 这篇文章主要介绍解决java中插入mysql中文乱码的方法,文中介 ...

  8. python3 文本处理_解决python3 写入中文文本查看为乱

    在python3中我们直接使用 f = open("file","w") 然后写入中文时,我们先关闭然后再查看,时没问题的,但是如果我们在文本里面查看会正常的, ...

  9. sqlserver中文显示问号_解决 SecureCRT 和 SecureFX 中文乱码

    引言 最近老是有小伙伴给我发消息说,下载的 SecureCRT 和 SecureFX 安装打开后连接了自己的服务器或虚拟机后会出现中文乱码,每次都要给一一回复,我倒没事,主要是有时候因为工作的原因,所 ...

最新文章

  1. 修改以服务方式启动tomcat7的堆内存设置
  2. shiro 没有注销再登录_Shiro 详细介绍 068
  3. Java通过JDBC来连接SqlServer数据库
  4. Unix/Linux常用命令及配置
  5. 操作系统 实验3【动态分区存储管理】
  6. iPhone放大模式详解
  7. 理想的互联网服务后台框架的九个要点
  8. 【渝粤教育】国家开放大学2018年春季 7397-21T家庭教育咨询与辅导 参考试题
  9. shell 字典_腾讯T4周末不陪对象,就为了手打这份shell编程笔记
  10. 客户说发货慢怎么回复_女生微信说身体不舒服怎么回复关心她?
  11. 导致Oracle性能抖动的参数提醒
  12. Ubuntu14.04部署CEPH
  13. java能字典_适用于Java的任何字典定义API?
  14. 实训作业 4(界面2)
  15. c语言无符号扩展,C语言中的无符号扩展和带符号扩展
  16. 简单聊聊离散数学是什么
  17. python如何计算等额本息还款_等额本息还款方式计算
  18. GBS国标经纬度转高德经纬度
  19. Photoshop中曲线调整如何恢复
  20. Hi3512的IPCAM开发

热门文章

  1. 网站转化率与漏斗模型
  2. 解决aspx页面中关键词(keywords)和描述(descript)不显示问题
  3. expdp/impdp 使用总结
  4. 如何将安卓系统的手机屏幕同步显示在电脑上
  5. 到底是什么原因?让200多家企业参与区块链改革?
  6. android usb 投电视盒子,电脑还可以管理电视盒子?这样做就可以!
  7. php的惰性加载,thinkphp5.0的惰性加载
  8. 8个最好用的H5页面制作工具
  9. mixamo骨骼_Mixamo——在线三维人物角色骨骼自动绑定,上千动作库直接生成人物动画...
  10. 【转贴】你必须知道的20个故事