A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© sanguodouble1 中级黑马   /  2014-5-25 16:43  /  6363 人查看  /  22 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 sanguodouble1 于 2014-5-29 22:37 编辑

今天看到一道关于字符集的笔试题,然后总结了一下:
ASCII :英文一个字节
gb2312,gbk :中文两个字节,英文一个字节
       在中文系统中ansi一般指gb2312或gbk
       GB2312、GBK都属于双字节字符集 (DBCS)
Utf-8 :中文三个字节,英文一个字节
Unicode:中文两个字节,英文两个字 ,java中默认编码
以上我的理解没错吧?

如果没错的话,下面这个使我十分不解:

  1. public class Test {
  2.         public static void main(String[] args) throws UnsupportedEncodingException {
  3.                 String str1 = "我爱abc";
  4.                 String str2 = "a";
  5.                 byte[] buf1 = str1.getBytes("unicode");
  6.                 byte[] buf2 = str2.getBytes("unicode");
  7.                 System.out.println(buf1.length+"字节");
  8.                 for (byte c : buf1) {
  9.                         System.out.print(c + " ");
  10.                 }
  11.                 System.out.println();
  12.                 System.out.println(buf2.length+"字节");
  13.                 for (byte c : buf2) {
  14.                         System.out.print(c + " ");
  15.                 }
  16.         }
  17. }
复制代码
输出结果:
str1-----------12字节
-2 -1 98 17 114 49 0 97 0 98 0 99
str2-----------4字节
-2 -1 0 97


理论上,str1应该是10个字节,str2是两个字节啊
现在多出来了两个字节-2和-1,这个是什么东西呢?

评分

参与人数 1技术分 +1 收起 理由
黑妞~ + 1

查看全部评分

22 个回复

倒序浏览
:o:o:o:o:o
回复 使用道具 举报
这个问题我也没有见过,搜集了一下资料,自己也学习整理了一下,楼主可以参考下
Unicode规范中推荐的标记字节顺序的方法是BOM
1、所以在转换为Unicode是加入了BOM (Byte Order Mark) 可以理解为采用那种排序方式吧
2、如果接收者收到FEFF(-1,-2),就表明这个字节流是Big-Endian的;如果收到FFFE(-2,-1),就表明这个字节流是Little-Endian的。
3、在 Java 中直接使用Unicode 转码时会按照UTF-16LE 的方式拆分,并加上 BOM所以就是FFFE(-2,-1),
这就是为什么会有-2,-1了,Unicode
4、UTF8字节没有顺序,所以它可以被用来检测一个字节流是否是UTF-8编码的,所以在UTF-8 中没有这个内容,我们平时用UTF-8比较多,所以看不到这个。
  希望楼主多发这样的问题,大家一块学习

评分

参与人数 1技术分 +1 收起 理由
黑妞~ + 1

查看全部评分

回复 使用道具 举报 1 0
向前看向前走 发表于 2014-5-26 21:39
这个问题我也没有见过,搜集了一下资料,自己也学习整理了一下,楼主可以参考下
Unicode规范中推荐的标记字 ...

非常好
不过我估计Utf-8之所以没有BOM头,是因为utf-8可以根据每个字节的前几位来判定,

回复 使用道具 举报
额,-2 -1(FE FF)是unicode big endian标志
fe ff:big endian
ff fe: no big endian
按照上面的结果看好像一个char是3 byte,但java中一个char是2 byte,
其实java中无论什么字符集string都会以unicode编码来存储,所以每个char都是一个
unicode编码占两个byte。

import java.io.UnsupportedEncodingException;  
  
  
public class TestUtf8File {  
  
  /** 
   * @param args 
   * 
   */  
  public static void main(String[] args) throws UnsupportedEncodingException {  
  
    String s = "中国人";     
    byte[] b = s.getBytes("utf-8");  
    String s_utf8 = new String(b,"utf-8");  
    System.out.println(s_utf8.getBytes("utf-8").length);  
    System.out.println("utf-8 bytes:");  
    printByteArray(s_utf8.getBytes("utf-8"));  
    System.out.println("chars:");  
    printCharArray(s_utf8.toCharArray());  
      
    byte[] unicodeb= s.getBytes("unicode");  
    String s_unidode = new String(unicodeb,"unicode");  
    System.out.println("unicode bytes:");  
    printByteArray(s_unidode.getBytes("unicode"));  
  
  }  
    
  private static void printByteArray(byte[] b){  
    for(int i = 0;i < b.length; i++){  
      System.out.println((Integer.toString(b[i],16)));  
        
    }  
  }  
    
  private static void printCharArray(char[] c){  
    for(int i = 0;i < c.length; i++){  
      System.out.println(Integer.toString((byte)(c[i]>>8),16));  
      System.out.println(Integer.toString((byte)(c[i]&0xff),16));  
        
    }  
  }  
  
}  

结果是output:
9
utf-8 bytes:
-1c
-48
-53
-1b
-65
-43
-1c
-46
-46
chars:
4e
2d
56
-3
4e
-46
unicode bytes:
-2
-1
4e
2d
56
-3
4e
-46

评分

参与人数 1技术分 +1 收起 理由
李小然 + 1

查看全部评分

回复 使用道具 举报
sanguodouble1 发表于 2014-5-26 23:04
非常好
不过我估计Utf-8之所以没有BOM头,是因为utf-8可以根据每个字节的前几位来判定,

你可以再看看这个,就应该能理解了
UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是“奎”还是“乙”?
  UTF-8是不用排序的,而Unicode是可以多个字节表示的,是需要排序的。
回复 使用道具 举报
在 Java 中直接使用Unicode 转码时会按照UTF-16LE 的方式拆分
回复 使用道具 举报
、海 中级黑马 2014-6-12 19:38:07
8#
学习了!!

回复 使用道具 举报
学习          
回复 使用道具 举报
hmid 中级黑马 2014-6-21 20:28:29
10#
学习,顶
回复 使用道具 举报
学习了  
回复 使用道具 举报
学习了啊,谢谢啊。
回复 使用道具 举报
非常好   见识了
回复 使用道具 举报
前几位总结的挺好,学习方法受教了
回复 使用道具 举报
围观中。。。。学习大神结论
回复 使用道具 举报
楼主给力!!!
回复 使用道具 举报
牛逼,学习了!
回复 使用道具 举报
看不懂啊啊啊啊
回复 使用道具 举报
顶一下!!!!
回复 使用道具 举报
顶一个!!!!
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马