我在输入运行System.getProperties().list(System.out);时
显示:file.encoding=GB18030 //这说明系统的本地语言也是用的这个字符集
说明我现在java虚拟机默认用GB18030对字节和字符进行转换
如String str=new String(buf,0,len); //假设buf字节数组。现在就是用GB18030把buf转换为Unicode。
我现在用
FileInputStream fin =new FileInputStream("1.txt"); //1.txt中为“你好”
InputStreamReader ipr =new InputStreamReader(fin);
BufferedReader br =new BufferedReader(ipr);
System.out.println(br.readLine()); //正常显示 “你好”我看一下1.txt文件:格式--字体--然后看到字符集是GB2312
我的问题是用Reader读后,字符是怎么从GB2312编码,到unicode 最后再到GB18030在显示器上输出的?我的理解:(应该不能正常显示“你好”)
Reader读的是按GB2312编码的字节,然后java虚拟机将其按GB18030解码为unicode字符(这里就有问题了,应该是按GB2312解码才能得到正确的unicode字符),输出时按GB18030编码为字节(这里相当于又得到了GB2312编码的字节),最后按GB18030 打印显示(因为系统本地语言是GB18030 )。不知道我是哪理解错了 希望大家指正,顺便讲下Reader是怎么读的。谢谢
显示:file.encoding=GB18030 //这说明系统的本地语言也是用的这个字符集
说明我现在java虚拟机默认用GB18030对字节和字符进行转换
如String str=new String(buf,0,len); //假设buf字节数组。现在就是用GB18030把buf转换为Unicode。
我现在用
FileInputStream fin =new FileInputStream("1.txt"); //1.txt中为“你好”
InputStreamReader ipr =new InputStreamReader(fin);
BufferedReader br =new BufferedReader(ipr);
System.out.println(br.readLine()); //正常显示 “你好”我看一下1.txt文件:格式--字体--然后看到字符集是GB2312
我的问题是用Reader读后,字符是怎么从GB2312编码,到unicode 最后再到GB18030在显示器上输出的?我的理解:(应该不能正常显示“你好”)
Reader读的是按GB2312编码的字节,然后java虚拟机将其按GB18030解码为unicode字符(这里就有问题了,应该是按GB2312解码才能得到正确的unicode字符),输出时按GB18030编码为字节(这里相当于又得到了GB2312编码的字节),最后按GB18030 打印显示(因为系统本地语言是GB18030 )。不知道我是哪理解错了 希望大家指正,顺便讲下Reader是怎么读的。谢谢
这个解码过程通过字符集编码表进行。也就是编码绑定字符的关系映射。2.java 内码为unicode,解码成功了也就意味得到了正确的字符(用于表达),再使用unicode
编码方式进行编码存放在内存中。
文件读取是一个道理。stream 是流,没有表达的意味,和字符集无关。reader 是读,需要正确理解流,需要通过正确字符编码方式对流进行解码,
这个时候流和编码产生了关系。writer 是写,可以任意选择编码方式,对表达的信息(字符)进行编码,这个时候流是被序列化的byte.在java中 CharSet 也就是Java的字符和字节流的驱动。打印时,是将流输入到显示窗体,窗体也需要正确解析stream,才能和正确的字符关联。
我用inputstream来读,读到buf[]中
此时buf中的字节是不是还是按GBK编码编码的字节?
我要把他转化为unicode的string是不是还要在String构造函数中指定用GBK解码?(加入默认虚拟机使用别的字符集)而用reader读 就得直接在构造reader时指定用GBK解码,才能得到正确的unicode?
请看一下String的构造函数,无参的String(byte[])会调用下面的构造函数,
在将byte[]转换成字符串的过程中,会使用系统默认的编码方式解码。
所以你用InputStream读到的byte[],在均使用系统默认编码时,无需在
String的构造函数中特别指定解码方式,当然也可以加。public String(byte bytes[], int offset, int length) {
checkBounds(bytes, offset, length);
char[] v = StringCoding.decode(bytes, offset, length);
this.offset = 0;
this.count = v.length;
this.value = v;
}static char[] decode(byte[] ba, int off, int len) {
String csn = Charset.defaultCharset().name();
try {
return decode(csn, ba, off, len);
...
}
char才是表现的基础,byte仍然是存储和通信的单位。