我在输入运行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是怎么读的。谢谢
 

解决方案 »

  1.   

    GB18030是对GBP312的扩展,是包含关系吧
      

  2.   

    楼上说的对,两个是包含关系。这个理解少了点步骤。1.byte[] 是针对传输和存储,它不能作为表示,如果要作为表示,需要对它进行正确的解码。
    这个解码过程通过字符集编码表进行。也就是编码绑定字符的关系映射。2.java 内码为unicode,解码成功了也就意味得到了正确的字符(用于表达),再使用unicode
    编码方式进行编码存放在内存中。
    文件读取是一个道理。stream 是流,没有表达的意味,和字符集无关。reader 是读,需要正确理解流,需要通过正确字符编码方式对流进行解码,
    这个时候流和编码产生了关系。writer 是写,可以任意选择编码方式,对表达的信息(字符)进行编码,这个时候流是被序列化的byte.在java中 CharSet 也就是Java的字符和字节流的驱动。打印时,是将流输入到显示窗体,窗体也需要正确解析stream,才能和正确的字符关联。
      

  3.   

    还有 加入一个txt文件是用GBK编码的。
    我用inputstream来读,读到buf[]中
    此时buf中的字节是不是还是按GBK编码编码的字节?
    我要把他转化为unicode的string是不是还要在String构造函数中指定用GBK解码?(加入默认虚拟机使用别的字符集)而用reader读 就得直接在构造reader时指定用GBK解码,才能得到正确的unicode?
      

  4.   

    Inputstream读出来就是实际的文件中byte,和文件的编码是一致的。
    请看一下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);
            ...
    }
      

  5.   

       使用默认的编码方式初始化String得看你的byte的编码方式是否与默认的一致。养成设置的习惯,不要忽略了。
        
        char才是表现的基础,byte仍然是存储和通信的单位。
      

  6.   

    GB2312, GBK, GB18030 这三种汉字的编码结构都是一样的,都是向左兼容的。我好像没看明白你要问啥?
      

  7.   

    最好都先用包装流弄成字节形式的   到时候就可以new String(xx.getBytes(),XX)设置编码了