- 浏览: 236279 次
- 性别:
- 来自: 济南
文章分类
最新评论
-
糯米烧麦:
按上文说明ws发布成功了,但浏览器输入url?wsdl报404 ...
使用JAX-WS的Provider和 Dispatch发布WebService的例子 -
gongmingwind:
我设定后就OK了
使用Servlet实现文件下载的时候,避免浏览器自动打开文件 -
fanhang116:
为什么设定了后还是自动打开呢.
使用Servlet实现文件下载的时候,避免浏览器自动打开文件
package example.encoding; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.nio.charset.Charset; import java.util.Iterator; import java.util.Set; import java.util.SortedMap; /** *//** * <pre> * The Class IOEncodeTest is a tester class for java encoding. Mainnaly contains * two parts: * 1.Test written by FileWriter, with or without given character encoding value * 2.Test written by OutputStreamWriter, with or without given character encoding value * </pre> * * @author Paul Lin * @version 1.0 */ public class OutputEncodingTest { private static String word = "Hello world! 中国"; private static final String ENCODING_EN = "ISO-8859-1"; private static final String ENCODING_CN = "GB2312"; private static final String ENCODING_UTF = "UTF-8"; private static final String DEFAULT_SYSTEM_ENCODING = System .getProperty("file.encoding"); /** *//** * The main method. * * @param args the arguments */ public static void main(String args[]) { OutputEncodingTest tester = new OutputEncodingTest(); tester.testFileWriter(); tester.testOutputStreamWriter(); } /** *//** * Test file writer. */ public void testFileWriter() { // Create test result folder String resultFolder = createResultFolder(System .getProperty("user.language"), getBasePath()); // With default platform encoding writeByFileWriter(word, resultFolder); // With given system file.encoding property writeByFileWriter(word, ENCODING_EN, resultFolder); writeByFileWriter(word, ENCODING_CN, resultFolder); writeByFileWriter(word, ENCODING_UTF, resultFolder); } /** *//** * Test output stream writer. */ public void testOutputStreamWriter() { // Create test result folder String resultFolder = createResultFolder(System .getProperty("user.language"), getBasePath()); // With default platform encoding writeByOutputStreamWriter(word, resultFolder); // With given system file.encoding property writeByOutputStreamWriter(word, ENCODING_EN, resultFolder); writeByOutputStreamWriter(word, ENCODING_CN, resultFolder); writeByOutputStreamWriter(word, ENCODING_UTF, resultFolder); } /** *//** * Prints the available charset. */ public void printAvailableCharset() { SortedMap<String, Charset> charsets = Charset.availableCharsets(); Set<String> charsetKeys = charsets.keySet(); System.out.println("\n<<<< Canonical name -- Display name -- " + " Can encode >>>>\n"); Iterator<String> i = charsetKeys.iterator(); while (i.hasNext()) { String key = (String) i.next(); Charset charset = (Charset) charsets.get(key); String displayName = charset.displayName(); boolean canEncode = charset.canEncode(); System.out.println(key + " - " + displayName + " - " + canEncode); } } /** *//** * Write by file writer. * * @param content the content */ private void writeByFileWriter(String content, String destination) { String defaultEncoding = System.getProperty("file.encoding"); System.out.println("Using default system encoding: " + defaultEncoding); writeByFileWriter(content, defaultEncoding, destination); } /** *//** * Write by file writer. * * @param content the content * @param encoding the encoding */ private void writeByFileWriter(String content, String encoding, String destination) { printDebugInformation("FileWriter", encoding, content); // Get system default encoding String defaultEncoding = System.getProperty("file.encoding"); // Reset underlying platform character encoding if (!defaultEncoding.equalsIgnoreCase(encoding)) { System.setProperty("file.encoding", encoding); } // Save as file with given encoding value String file = returnFileName(destination, "write_by_filewriter_", encoding, ".txt"); try { Writer writer = new BufferedWriter(new FileWriter(file)); writer.write(content); writer.flush(); writer.close(); } catch (IOException ioe) { ioe.printStackTrace(); } // Reset character encoding to system default value resetDefaultSystemEncoding(); } /** *//** * Write by output stream writer. * * @param content the content */ private void writeByOutputStreamWriter(String content, String destination) { String defaultEncoding = System.getProperty("file.encoding"); System.out.println("Using default system encoding: " + defaultEncoding); writeByOutputStreamWriter(content, defaultEncoding, destination); } /** *//** * Write by output stream writer. * * @param content the content * @param encoding the encoding */ private void writeByOutputStreamWriter(String content, String encoding, String destination) { printDebugInformation("OutputStreamWriter", encoding, content); // Save as file with given encoding value String file = returnFileName(destination, "write_by_outputStreamWriter_", encoding, ".txt"); try { Writer writer = new PrintWriter( new BufferedWriter(new OutputStreamWriter( new FileOutputStream(file), encoding))); writer.write(content); writer.flush(); writer.close(); } catch (FileNotFoundException fnfe) { fnfe.printStackTrace(); } catch (UnsupportedEncodingException uee) { uee.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } // Reset character encoding to system default value resetDefaultSystemEncoding(); } /** *//** * Gets the base path. * * @return the base path */ private String getBasePath() { StringBuffer finalPath = new StringBuffer(); String dir = System.getProperty("user.dir"); finalPath.append(dir); finalPath.append((dir.endsWith("\\") || dir.endsWith("/")) ? "" : "/"); finalPath.append("src").append("/"); finalPath.append("example").append("/"); finalPath.append("encoding").append("/"); return finalPath.toString(); } /** *//** * Return file name. * * @param basePath the base path * @param prefix the prefix * @param content the content * @param subfix the subfix * * @return the string */ private String returnFileName(String basePath, String prefix, String content, String subfix) { StringBuffer name = new StringBuffer(basePath); if ((!basePath.endsWith("\\") && (!basePath.endsWith("/")))) { name.append("/"); } name.append(prefix); name.append(content); name.append(subfix); return name.toString(); } /** *//** * Creates the result folder. * * @param platform the platform * @param fullPath the full path * * @return the string */ private String createResultFolder(String platform, String fullPath) { StringBuffer resultFolder = new StringBuffer(); if (fullPath.endsWith("\\") || fullPath.endsWith("/")) { resultFolder.append(fullPath); } else { resultFolder.append(fullPath).append("/"); } resultFolder.append("Test_Result_Of_").append(platform); File file = new File(resultFolder.toString()); if (!file.exists()) { file = new File(resultFolder.toString()); file.mkdir(); return resultFolder.toString(); } else { return file.getAbsolutePath(); } } /** *//** * Prints the debug information. * * @param writerName the writer name * @param encoding the encoding */ private void printDebugInformation(String writerName, String encoding, String content) { StringBuffer msg = new StringBuffer(); msg.append("\n<<<<----------------------------------"); msg.append(" Test written by ").append(writerName); msg.append(" with encoding ").append(encoding); msg.append(" ---------------------------------->>>>\n"); msg.append(" \nOriginal string: ").append(content).append("\n"); System.out.println(msg.toString()); } /** *//** * Reset default system encoding. */ private void resetDefaultSystemEncoding() { System.setProperty("file.encoding", DEFAULT_SYSTEM_ENCODING); } }
【1】中文平台情况下,测试结果如下:
1.如果采用FileWriter,并指定GBK编码:编码后字符长度为15,可以正常保存和读取
2.如果采用FileWriter,并指定UTF-8编码:编码后字节长度为16,可以正常保存和读取
3.如果采用FileWriter,并指定ISO8859-1编码:编码后字节长度为17,可以正常保存和读取
4.如果采用OutputStreamWriter,并指定GBK编码:编码后字符长度为15,可以正常保存和读取
5.如果采用OutputStreamWriter,并指定UTF-8编码:编码后字节长度为16,可以正常保存和读取
6.如果采用OutputStreamWriter,并指定ISO-8859-1编码:编码后字节长度为17,变成?
【2】英文平台情况下,测试结果如下:
1.如果采用FileWriter,并指定GBK编码:编码后字符长度为15,变成?
2.如果采用FileWriter,并指定UTF-8编码:编码后字节长度为16,变成?
3.如果采用FileWriter,并指定ISO-8859-1编码:编码后字节长度为17,变成?
4.如果采用OutputStreamWriter,并指定GBK编码:编码后字符长度为15,可以正常保存和读取
5.如果采用OutputStreamWriter,并指定UTF-8编码:编码后字节长度为16,可以正常保存和读取
6.如果采用OutputStreamWriter,并指定ISO-8859-1编码:编码后字节长度为17,变成?
【结论】
①在中文平台下,如果使用FileWriter,不论你如何设置字符集都不会起作用。因为它采用的是默认的系统字符集。即便你设置了System.setProperty("file.encoding", "ISO-8859-1"),或者在运行时给予参数-Dfile.encoding=UTF-8都不会起作用。你会发现它最终还是都已"GB2312"或者"GBK"的方式保存。
在中文平台下,如果使用OutputStreamWriter,则在后台写入时会把字符流转换成字节流,此时指定的编码字符集就起作用了。可以看到在指定GBK、UTF-8的情况下中文可以正常的保存和读取,同时文件按照我们给定的方式保存了。而对于ISO-8859-1则变成了?,这再次证明了采用ISO-8859-1是不能保存中文的,而且会因为中文编码在ISO-8859-1的编码中找不到对应的字符而默认转换成?。
②在英文平台下,如果使用FileWriter,不论你如何设置字符集同样都不会起作用。所有的文件都将按照ISO-8859-1的编码方式保存,毫无疑问地变成了?。在英文平台下,如果使用OutputStreamWriter,则只有当我们把字符和文件的编码方式正确设置为GBK、UTF-8的情况下,中文才能正确的保存并显示。
③通过上述的实验证明,为了确保在不同的平台下,客户端输入的中文可以被正确地解析、保存、读取。最好的办法就是使用OutputStreamWriter配合UTF-8编码。
如果不想使用UTF-8编码,那么可以考虑使用GB2312,不建议使用GBK、GB18030。因为对于某些老式的文本编辑器,甚至不支持GBK、GB18030的编码,但是对于GB2312则是一定支持的。因为前两者都不是国标但后者是。
④关于String的getBytes(),getBytes(encoding)和new String(bytes, encoding)这三个方法,非常值得注意:
A.getBytes():使用平台默认的编码方式(通过file.encoding属性获取)方式来将字符串转换成byte[]。得到的是字符串最原始的字节编码值。
B.getBytes(NAME_OF_CHARSET):使用指定的编码方式将字符串转换成byte[],如果想要得到正确的字节数组,程序员必须给出正确的NAME_OF_CHARSET。否则得到的就不会得到正确的结果。
C.new String(bytes, encoding):如果我们在客户端使用UTF-8编码的JSP页面发出请求,浏览器编码后的UTF-8字节会以ISO-8859-1的形式传递到服务器端。所以要得到经HTTP协议传输的原始字节,我们需要先调用getBytes("ISO-8859-1")得到原始的字节,但由于我们客户端的原始编码是UTF-8,如果继续按照ISO-8859-1解码,那么得到的将不是一个中文字符,而是3个乱码的字符。所以我们需要再次调用new String(bytes,"UTF-8"),将字节数组按照UTF-8的格式,每3个一组进行解码,才能还原为客户端的原始字符。
D.String的getBytes()、getBytes(NAME_OF_CHARSET)方法都是比较微妙的方法,原则上:传输时采用的是什么编码,我们就需要按照这种编码得到字节。new String(bytes, NAME_OF_CHARSET)则更加需要小心,原则上:客户端采用的是什么编码,那么这里的NAME_OF_CHARSET就必须和客户端保持一致。
例如JSP页面是GBK,那么我们接收页面传递而来的参数时就必须使用new String(parameter.getBytes("ISO-8859-1"), "GBK");如果使用了错误的解码方式,如使用了UTF-8,那么得到的很有可能就是乱码了。
也就是说:GBK--->ISO-8859-1--->GBK、UTF-8--->ISO-8859-1--->UTF-8的转换过程是没有问题的。但是GBK--->ISO-8859-1--->UTF-8、UTF-8--->ISO-8859-1--->GBK的字节直接转码则可能导致乱码,需要另外的转换过程。
记住:
谨慎地使用getBytes(NAME_OF_CHARSET)和new String(bytes, NAME_OF_CHARSET),除非你很清楚的知道原始的字符编码和传输协议使用的编码。
推荐使用基于服务器的配置、过滤器设置request/response的characterEncoding、content type属性。还有就是JSP页面的pageEncoding属性、HTML meta元素的content type属性。尽量避免频繁的在代码中进行字符串转码,即降低了效率又增加了风险
发表评论
-
Volatile使用场景
2014-11-26 17:39 860Volatile的特性:可见性,但不互斥.怎么理解这句话, ... -
Java线程(四):线程中断、线程让步、线程睡眠、线程合并 .
2014-10-28 15:49 827有人会问:JDK5之后有了更完善的处理多线程问题的类(并发包 ... -
Java线程(三):线程协作-生产者/消费者问题
2014-10-28 15:35 722上一篇讲述了线程的 ... -
Java线程(二):线程同步synchronized和volatile
2014-10-24 18:19 814上篇通过一个简单 ... -
Java线程(一):线程安全与不安全
2014-10-24 18:01 710当我们查看JDK API的时候,总会发现一些类说明写着,线程 ... -
Java线程(七):Callable和Future
2014-10-24 17:51 497接着上一篇继续并发 ... -
final修饰符
2012-07-09 16:30 884final修饰符1.final 可以修饰变量,被fina ... -
super的限制
2012-07-09 15:49 840super的限制1.子类方法不能直接使用 return sup ... -
JAVA继承在处理成员变量和方法时是有区别
2012-07-09 15:27 1061JAVA继承在处理成员变 ... -
System.getProperty()参数大全
2011-09-29 09:33 973内容来源网站: http://blog.sina.com.cn ... -
字符集和编码
2011-07-07 14:48 829很久很久以前,有一群 ... -
【Java基础专题】编码与乱码(07)---native2ascii命令的用法
2011-07-05 11:54 1093【1】native2ascii命令的语 ... -
【Java基础专题】编码与乱码(06)---字符的各种值转换
2011-07-05 11:53 1021package example.encoding; /* ... -
【Java基础专题】编码与乱码(05)---GBK与UTF-8之间的转换
2011-07-05 11:51 1283【GBK转UTF-8】 在很多论坛、网上经常有网友问“ 为什么 ... -
【Java基础专题】编码与乱码(03)----String的toCharArray()方法
2011-07-05 11:43 1210package example.encoding; i ... -
【Java基础专题】编码与乱码(02)---String的getBytes([encoding])方法
2011-07-05 11:41 1064package example.encoding; im ... -
【Java基础专题】编码与乱码(01)---编码基础
2011-07-05 11:30 933Unicode中文“艺”字: 827A二进制的“艺”字编码:1 ... -
JavaEE防止中文乱码的设置
2011-07-04 17:29 1515在基于J2EE的B/S应用中,中文乱码是一个永恒的主题,永远都 ... -
JAVA 序列化
2011-05-21 13:49 872当进行序列化的时候: 首先JVM会先调用writeReplac ...
相关推荐
jd-gui.exe反编译后复制中文是乱码,xml,yml...等配置文件中文显示为乱码,本资源修改了编码,反编译后中文随意复制,配置文件显示也是正常的
java字符集编码乱码详解
最近的项目(Delphi开发),需要经常和java语言开发的系统进行数据交互(Socket通信方式),数据编码约定采用UTF-8编码。 令我无语的是:JAVA系统那边反映说,Delphi发的数据他们收到是乱码,而我这边(Delphi7,...
乱码 编码方式解决 gbk ISO8859-1 utf8 编码 乱码 编码方式解决 gbk ISO8859-1 utf8 编码
主要介绍了Java避免UTF-8的csv文件打开中文出现乱码的方法,结合实例形式分析了java操作csv文件时使用utf-16le编码与utf8编码相关操作技巧,需要的朋友可以参考下
包含 Java与编码问题串讲之三--乱码 Java与编码问题串讲之二--如何理解java采用Unicode编码 Java与编码问题串讲之一--ANSI、Unicode与UTF8
能够集成到Source Insight中,解决JAVA文件乱码问题
在eclispe的项目中,有存在项目字符集和工作空间字符集不匹配,该jar只能将项目文件中的.java结尾的文件转为utf8编码,并且源文件必须为gbk编码的,否则乱码
idea、Eclipse等项目导入.java文件中文乱码完美解决方案:文件夹下所有GBK编码的.java一键转为utf-8,操作方式:将GBK2UTF8.jar文件考到需要转码项目目录,在当前位置运行控制台,输入命令java -jar GBK2UTF8.jar,...
“字符与编码”是一个被经常讨论的话题,而时常出现的乱码对于... 而对于JAVA来说,在JSP输出、文件读写、甚至数据库访问等环节上,都有可能出现乱码现象,而之所以会出现乱码,都与编码及转码有着莫大的关系。。。
解决JAVA读取properties中文乱码问题
java 识别文件的编码格式 读取文件的编码 utf-8 gbk gb2312 java 编码 java 获取文件编码格式 java 乱码查找
不需要关心接受的字符串编码是UTF_8还是GBK,还是ios-8859-1,自动转换为utf-8编码格式,无需判断字符串原有编码,用法://处理编码String newStr = GetEncode.transcode(oldStr);
近正在做一个项目,其中遇到了一个问题是java与.NET之间的通信问题。具体的问题是这样的: 客户端使用java,服务器端使用的是C#。两者之间使用基于TCP的Socket通信方式。可是,做了一个测试小例子,结果从客户端...
sftp解决上传中文乱码,sftp.setFilenameEncoding("GBK");修改是不起作用的,修改源码后重新导出的jar包。
java编码中的中文问题是一个老生常谈的问题了,但一直没有一个清晰的解释,本文作者将通过《java 中文乱码 解决之道》彻底分析、解决java中文乱码问题。
eclipse下批量转java GBK编码文件到UTF-8,java类,非可执行文件,在eclipse下运行即可
freemarker入门实例,直接运行(junit)测试类
从编码角度分析了java编译后在控制台和web等终端显示乱码问题。
(3)使用my eclipse /Eclipse编写程序4、程序编码时,必须严格遵守java程序标识符的一般约定,并要加适量的注释。5、系统基本能运行,程序结构合理层次清晰6、各种技术的综合应用7、在myeclipse/Eclipse中的控制台...