Java 中的字符集 (控制台,windows,linux)
来源:互联网 发布:小米路由器网络诊断691 编辑:程序博客网 时间:2024/05/11 12:04
看本文之前,请先弄清楚什么是unicode,utf8,utf16。不清楚请移步百度百科http://baike.baidu.com/view/40801.htm
Java的String内部有private final char value[] ,使用UTF-16编码来存储。也就是说,不管是什么样的字符串,只要是存储在String对象中的,就是UTF-16编码。
那我们读取的文件的字符集有很多种,怎么办呢。String有个构造函数String(byte[] bytes, String charsetName) ,从文件中读取了bytes后,可以用这个来指定bytes的字符集charset,Java会自动讲bytes从charset转化成UTF-16,然后存到String中。没有指定的话,那么使用系统默认的字符集。
接下来,还有一个问题是,如果我在源代码中写了这样的语句,如
String test="我是中文"
那么,是怎么处理的呢。
使用下面的代码测试:
- public class Test {
- public static void main(String args[]) {
- String test="我是中文";
- System.out.println(test);
- }
- }
- public class Test {
- public static void main(String args[]) {
- String test="我是中文";
- System.out.println(test);
- }
- }
第一次,使用记事本写,保存。
javac Test.java
java Test
一切正常。
第二次,直接使用记事本,把文件另存为UTF8。
这个错误的原因是,记事本自作聪明地给文件前面多加了三个字节。用UE打开看就能看到了。
关于这个问题,google一下"记事本 UTF8 BOM"。前人已经写得很清楚了。
OK。我们使用UE将这三个字节删掉。然后
javac Test.java
java Test
可恶的乱码出现了。
为什么会出现乱码呢?
javac Test.java做了这样的事,首先javac不知道文件的编码,因此使用系统默认的字符集(GBK),也就是说javac把UTF8编码的文件当成了GBK编码的文件。因此,当javac读到"我是中文"时,他看到的是这四个字的UTF8编码的二进制形式,但是他将这些当成GBK编码了。
于是,他就将这些bytes从GBK编码转化成UTF16的String对象(这是个错误的转化,因为得到的就不是"我是中文"的正确的UTF16编码了)。注意,转化完后还是可以得到二进制的字节,javac把这些保存在.class文件中。
这样呢,java Test运行时,输出的就是乱码了。
那么,如果使用java Test > temp.txt,然后用UE打开temp.txt,会看到什么呢?
恩,不是乱码,而是"我是中文"。
这又是为什么呢?
将"我是中文"的UTf8编码记为A
将A用GBK编码转化成的UTF16编码记为B
这样,B就是保存在.class中的内容
System.out做了什么事呢?他先将.class中的B从UTF16转化为GBK(系统默认编码)编码,这样得到了A。
然后把A传给控制台输出。控制台使用的编码也是默认的GBK,因为显示出来就是乱码了。
但是使用重定向后,temp.txt中保存的二进制字节正好是A。
当用UE打开后temp.txt,UE自动根据temp.txt的文件监测编码,发现是UTF8编码的二进制字节,因此使用的UTF8来显示,当然就正常了。(>_<记事本真的很弱)
最后,补充一点,对于源码中的非字符串 部分,javac先按文件的编码解析,然后将所有遇到的源码(除引号中的字符串外),都使用UTF8保存在class文件中。有兴趣的不妨自己打开class文件看看。
下面这个文件我用UTF8 保存:
- public class Test {
- public static void main(String args[]) {
- String 我是中文="我是中文";
- System.out.println(我是中文);
- }
- }
- public class Test {
- public static void main(String args[]) {
- String 我是中文="我是中文";
- System.out.println(我是中文);
- }
- }
然后我用javac Test.java,就报错了。
原因是,javac发现里面有非法的GBK编码。。。。。。呵呵,经常在Windows写代码,然后放到Linux下手动编译的,可能会觉得这个很熟悉吧。
因为Windows默认编码是GBK,Linux默认编码是UTF。
当你写一个GBK编码的Test.java,然后放到Linux下直接javac Test.java,如果文件中有中文的话,一般都会有错误。
建议,如果手动使用javac编译的话,尽量加上encoding选项,避免不必要的问题出现。
如:javac -encoding utf8 Test.java
其中utf8是Test.java文件的编码
- Java 中的字符集 (控制台,windows,linux)
- java中的字符集
- java中的字符集编码
- java中的控制台输入
- windows与linux字符集转换
- Java调用Windows控制台命令
- Java调用Windows控制台命令
- java中的字符集的编码
- Java中的字符集编码入门
- 如何调出Java的控制台(windows 7 x64)
- linux中的tty,控制台,虚拟终端,串口,console(控制台终端)详解和区别
- 宽字符集in linux and windows
- Java-Charset(字符集)
- windows 字符集
- windows 字符集
- JConsole(Java 实现Windows 下CMD控制台)
- Java调用Windows控制台命令方法介绍
- JAVA代码执行Windows控制台命令
- quartz 框架定时任务,使用spring @Scheduled注解执行定时任务
- PHP 总结
- TP-LINK WR703N 变砖救活
- Codeforces_9D-How many trees?
- yum&apt-get
- Java 中的字符集 (控制台,windows,linux)
- POJ 1258 Agri-Net 【最小生成树入门题目】
- UVa 102 - Ecological Bin Packing
- SSH框架应用中常用Jar包用途介绍
- Unicode、UTF-8 和 ISO8859-1到底有什么区别〈转〉Unicode、UTF-8 和 ISO8859-1到底有什么区别
- UVa 100 - The 3n + 1 problem
- 日志服
- acm入门
- 关于Linux下MysqL的默认字符集的修改(转)