XMLWriter编码问题
我们来看写文件时用到的XMLWriter,他提供以下几种构造方法:
?XMLWriter()
?XMLWriter(OutputFormat format)
?XMLWriter(OutputStream out)
?XMLWriter(OutputStream out, OutputFormat format)
?XMLWriter(Writer writer)
?XMLWriter(Writer writer, OutputFormat format)
最简单常用的可能是new XMLWriter(new FileWriter(...))这样的形式。
可如果你一旦这么用,就会造成编码问题。
由于dom4j对于文件编码的选择是才用java本身类的处理方式(可以从源码看到),
这么写就是采用FileWriter的处理方式,
而FileWriter是不提供对编码的处理的。于是会调用系统自身的编码,比如用中文操作系统,
编码方式就是gbk,然后默认的,他赫然会在文件头写上
<!--l version="1.0" encoding="UTF-8-->
也就是说,他以当前操作系统的编码保存文件,并且竟然自动添加文件头为"utf-8"格式,
这会导致很多程序无法读取正确编码,而且具有很差的移植性(比如在windows下开发,
放到linux服务器下跑,毕竟一般linux服务器默认local都是utf-8)。
解决途径一:使用new XMLWriter(new FileOutputStream(...))方法。这样做,
因为dom4j默认使用utf-8编码,即xml文件头
默认编码方式,并且内容也会使用utf-8保存,这样可以做到一致的编码,不会出问题。
解决途径二:使用new XMLWriter(new FileOutputStream(...), outputFormat)的构造方法。
OutputFormat xmlFormat = OutputFormat.createPrettyPrint();
xmlFormat.setEncoding("utf-8");
XmLWriter writer = new XMLWriter(new FileOutputStream(...), xmlFormat);
writer.write(document);
writer.close(); 如上,setEncoding可以设置存储的文件编码格式,createPrettyPrint是
得到美化xml格式输出。这样的话,在不同的环境下可以获得同样的编码读写,并且真正保证了
文件标称与实际编码的一致性。
【注意】如果你使用OutputFormat是为了设置文件编码,那千万别用
XMLWriter(new FileWriter(...),outputFormat)构造方法,因为前面已经说了,
FileWriter不会处理编码,所以即使你使用format.setEncoding("utf-8");他仍然不会使用
utf-8编码,而只是把文件头指定为utf-8,这类似不使用outputFormat的情况。
而网上好多人举例用了
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"),format);
那是因为他们format.setEncoding("gbk");而windows默认就是gbk,这当然使实际编码与
标称的配套了。但实际上,这种方法是不正确的,java并没有按你写的"gbk"进行编码,而是
使用了系统默认编码而已,放到linux就会出现错误,所以一定的小心。 把编码交给操作系统
来控制一向是罪恶的,包括java其他地方的参数传递等,如request的参数传递,其他文件读
写,如果不使用编码过滤器,不进行编码指定,可能使得整个系统失去移植性,并产生完全不
可预期的错误。找起来头大不说,有时候看到encoding="UTF-8",实际上却是gkb编码会让
你错过关键调试点。还有就是记事本的罪恶性,用记事本打开不同编码的文件,往往得不到预
期的效果,而且你无从得知他到底是用何种编码打开,一般使用EditPlus指定编码打开会好很
多。希望对你有帮助!