一、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刘
四、