encode decode作用,以及为什么会出现乱码呢?如何准确检查字符长度?
为什么会出现乱码呢?
文件 存的格式
和 读取格式
不一致就会乱码了
简单来说是因为: 编码 (encode) 和 解码(decode)时用了不同
或者不兼容
的字符集
encode作用:是将unicode编码的字符串编码
成二进制数据
如:str2.encode('utf-8')→使用utf-8编码
decode作用:是将二进制数据解码
成unicode
简单的来说:decode就是把二进制数据(bytes)转化成人看的懂
得英文或者汉字(decode用的比较多)
如:str1.decode('utf-8')→使用utf-8解码
encode,decode举例说明
String urlString = "TOP 好的";//TOP 好的
urlString = URLEncoder.encode(urlString, "utf-8");//encode:--->TOP+%E5%A5%BD%E7%9A%84
urlString = URLDecoder.decode(urlString, "utf-8");//decode:--->TOP 好的
注意:
计算机内存
中统一使用Unicode
,使用UTF-8
编码为二进制数据然后保存到硬盘
/传输
例如:
- 用记事本编辑的时候: 文件(二进制数据)→(UTF-8解码)→内存(Unicode字符)→(UTF-8编码)→文件(二进制数据)
- 浏览网页的时候:服务器会把动态生成的
Unicode
内容→(UTF-8编码)→(二进制数据)传输→(UTF-8编码)→Unicode
内容到浏览器 - 我们平常在做编码转换时候,通常用
unicode
作为中间编码
。先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码格式
//为了让中文字符适应某些特殊要求(如http header头要求其内容必须为iso8859-1编码),可能会通过将中文字符按照字节方式来编码的情况
String aaa = new String("知".getBytes("UTF-8"), "ISO8859-1");
//把 '知' 按照 UTF-8 encode ---> [-25, -97, -91] 再按照 ISO8859-1 decode 成 乱码'知'
String bbb = new String(aaa.getBytes("ISO8859-1"), "UTF-8");
//把乱码'知' 按照 ISO8859-1 encode ---> [-25, -97, -91], 再按照 UTF-8 decode 成 '知'
String.getBytes(Stringdecode)
//方法会根据指定的encode编码返回某字符串在该编码下的byte数组表示
String.getBytes(Stringdecode)
byte[] b_utf8 = "知".getBytes("UTF-8"); // b_utf8的长度为3
11100111 10011111 10100101
[-25, -97, -91] //没有转化成16进制,而是有符号的十进制
byte[] b_gbk = "知".getBytes("GBK");
[-42, -86]
byte[] b_unicode = "知".getBytes("unicode"); // b_unicode长度为4
[-2, -1, 119, -27]
byte[] b_iso88591 = "知".getBytes("ISO8859-1");// b_iso88591的长度为1
[63]//所有中文都是这个数值,因为不识别
new String(b_utf8, “UTF-8”);
//通过new String(byte[], decode),根据指定的decode编码来将byte[]解析成字符串
String s_utf8 = new String(b_utf8, "UTF-8");
知
String s_gbk = new String(b_gbk, "GBK");
知
String s_unicode = new String(b_unicode, "unicode");
知
String s_iso88591 = new String(b_iso88591, "ISO8859-1");
?//encode都是不对的,decode指定是错的
准确检查字符长度?
在开发时会检查字符长度,以免数据库字段的长度不够而报错,考虑到中英文的差异,肯定不能用String.length()
方法判断,而需采用String.getBytes().length
;还可以用指定编码方式查看长度:String.getBytes("GBK").length
Set<String> charsetNames = Charset.availableCharsets().keySet();
System.out.println("-----the number of jdk1.67's charset is " + charsetNames.size() + "-----");
for (Iterator it = charsetNames.iterator(); it.hasNext();) {
String charsetName = (String) it.next();
System.out.println(charsetName);
}