有没有办法在java中将大型XML文件(500 + MBs)从"Windows-1252"编码转换为"UTF-8"编码?
当然:
- 打开一个包裹在
InputStreamReader
中的FileInputStream
,使用 Windows-1252 进行输入 - 打开一个用 UTF-8 编码包裹在
OutputStreamWriter
中的FileOutputStream
作为输出 - 创建一个缓冲区字符数组(例如 16K)
-
反复读取数组并写入已写入的内容:
char[] buffer = new char[16 * 1024]; int charsRead; while ((charsRead = input.read(buffer)) > 0) { output.write(buffer, 0, charsRead); }
- 之后不要忘记关闭输出!(否则,可能会有永远不会写入磁盘的缓冲数据。
请注意,由于它是XML,您可能还需要手动更改XML声明,因为它应该指定它在Windows-1252中...
这在流式处理的基础上工作的事实意味着您无需担心文件的大小 - 它一次最多只能读取内存中的 16K 个字符。
这是一次性的还是需要反复运行并提高效率的工作?
如果是一次性的,我认为不需要Java编码。例如,只需运行查询"."
java net.sf.saxon.Query -s:input.xml -qs:. -o:output.xml
确保分配 3Gb 的内存。
如果你反复这样做并且想要一种流方法,你必须选择将其作为文本处理(如Jon Skeet建议的那样)或XML。将其作为 XML 执行的优点主要是 XML 声明将得到处理,并且字符引用将转换为字符。最简单的方法是使用 JAXP 身份转换:
Source in = new StreamSource(new File("input.xml"));
TransformerFactory f = TransformerFactory.newInstance();
Result out = new StreamResult(new File("output.xml"));
f.newTransformer().transform(in, out);
如果这是一次性的,Java可能不是最合适的工具。考虑iconv
:
iconv -f windows-1252 -t utf-8 <source.xml >target.xml
这具有流式传输的所有好处,而无需编写任何代码。
与 Michael 的解决方案不同,这不会处理 XML 声明。如有必要,请手动编辑它,或者,现在您使用的是 UTF-8,请省略它。