UTF8和GBK区别,以及读取文件存在BOM,第一个字符值为65279

一、GBK的文字编码:是双字节来表示的,即不论中、英文字符均使用双字节来表示,只不过为区分中文,将其最高位都定成1。

UTF-8编码:则是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24位(三个字节)来编码。对于英文字符较多的网站则用UTF-8节省空间。

所以如果是UTF8编码,则在外国人的英文IE上也能显示中文,而无需他们下载IE的中文语言支持包。 所以,对于英文比较多的论坛 ,使用GBK则每个字符占用2个字节,而使用UTF-8英文却只占一个字节。

ISO-8859-1:中文只占一个字节

 

二、首先了解一下BOM,字节顺序标记(英语:byte-order mark,BOM)是位于码点U+FEFF的统一码字符的名称。当以UTF-16或UTF-32来将UCS/统一码字符所组成的字符串编码时,这个字符被用来标示其字节序。它常被用来当做标示文件是以UTF-8、UTF-16或UTF-32编码的记号。【来自维基百科

 

读取文件代码,代码底层读取文件时,会根据不同编码的CharsetDecoder实现类来读取(比如UTF8编码):

 public static void main(String[] args) throws FileNotFoundException {
		FileReader reader = new FileReader(new File("data.txt"));
		int read;
		try {
			System.out.println(reader.getEncoding());
			while((read = reader.read())!=-1){
				System.out.println(read+":"+(char)(read));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

 

新建文本,内容为:

1411111哈哈

 1、当格式为以UTF8有BOM时:

输入结果:

UTF8
65279:
49:1
52:4
49:1
49:1
49:1
49:1
49:1
21704:哈
21704:哈

 

2、当格式为以UTF8无BOM时:

输入结果:

UTF8
49:1
52:4
49:1
49:1
49:1
49:1
49:1
21704:哈
21704:哈

 

注意:上面代码中,我们直接用char强转读取的int值,并不是因为不考虑ASCII码表,而是因为read()方法底层读取的是char字段,直接赋值给int返回的。

int read;
System.out.println(reader.getEncoding());
while((read = reader.read())!=-1){
	System.out.println(read+":"+(char)(read));
}
 read()方法,arg1[0]为char类型:
private int read0() throws IOException {
      Object arg0 = this.lock;
      synchronized(this.lock) {
         if(this.haveLeftoverChar) {
            this.haveLeftoverChar = false;
            return this.leftoverChar;
         } else {
            char[] arg1 = new char[2];
            int arg2 = this.read(arg1, 0, 2);
            switch(arg2) {
            case -1:
               return -1;
            case 0:
            default:
               assert false : arg2;

               return -1;
            case 2:
               this.leftoverChar = arg1[1];
               this.haveLeftoverChar = true;
            case 1:
               return arg1[0];
            }
         }
      }
   }
 三、一个ASCⅡ占用一个字节,所以假如在操作二进制流,比如发送http请求组装参数时,你把内容放入ByteArrayOutputStream,这时候你需要输入"xxxx?myname=liu刘",则操作如下示例:
os.write(URLEncoder.encode("xxxx", requestEncoding).getBytes());
os.write(63);//ASCⅡ代表?
os.write(URLEncoder.encode("myname", requestEncoding).getBytes());
os.write(61);//ASCⅡ代表=
os.write(URLEncoder.encode("liu刘", requestEncoding).getBytes());
其中用的URLEncoder编解码目的是因为http的get请求不支持中文,所以先编码一下,接受后解码可以预防乱码问题,英文编码前后不变化。示例:
		String content = "abc123ha刘";
		String encoderString = URLEncoder.encode(content, "utf-8");
		System.out.println(encoderString);
		String decodedString = URLDecoder.decode(encoderString, "utf-8");
		System.out.println(decodedString);
 输出:
abc123ha%E5%88%98
abc123ha刘
  四、  

猜你喜欢

转载自1181731633.iteye.com/blog/2355879
今日推荐