大家好,欢迎来到IT知识分享网。
对计算机而言,任何数字都是二进制的,字符也是用十六进制(其实也是二进制)来表示:比如”中文”,正常情况下(即没有错误的时候)存储为”4e2d 6587”,如果charset为”gbk”,则被编码为”d6d0 cec4”,然后返回字节”d6 d0 ce c4”.如果charset为”utf8”则最后是”e4 b8 ad e6 96 87”.如果是”iso8859-1”,则由于无法编码,最后返回 “3f 3f”(两个问号)。所以这里可以明确一个道理:不是我们看到的所有字符,都可以被解码,比如“ABCDEFG”,可以被解码为“utf-8”,也可以是“GBK”,甚至是“ASCII”,但是不能是”hex”,因为”HEX”不支持“G”这种编码格式。
也就是说,在不同编码格式下,字符的底层是不一样的,但是,我们明白一个道理就好:把字符正常显示就是一个查表的过程,当我们从网络,web,DB中接受数据的时候,我们得到肯定是一串01二进制(最底层),然后我们要做到找个“表”,去翻译这些二进制串,这个表就是字符编码。如server给我的是gbk的01序列,我们却用utf-8的01序列来做翻译,当然会乱码。所以乱码的根本原因在于我们没有找到一个张合适“翻译表”去翻译对方给我们的语言。
下面说说关于java中的字符串string的关于编码的方法吧:
1.String.getByte(“”); 这个函数是解码函数,就是说,原来的字符可以被哪种编码方式支持,我们就可以按照个编码过程来解码,这个函数返回的就是一串字节数组,也就是一个二进制的序列。
比如:
String str = "中国"; try { byte[] bytes = str.getBytes("gbk"); byte[] bytes2=str.getBytes("utf-8"); byte[] byte3=str.getBytes("ascii");//不支持 } catch (UnsupportedEncodingException e) { e.printStackTrace(); }
2.new String(byte[],”charset”) 这是java字符串处理的另一个标准函数,和上一个函数的作用相反,将字节数组按照charset编码进行组合识别,最后转换为unicode存储。参考上述getBytes的例子,”gbk” 和”utf8”都可以得出正确的结果”4e2d 6587”,但iso8859-1最后变成了”003f 003f”(两个问号)。
这个函数的使用示例如下:
try { String s="中国"; byte []b=s.getBytes("utf-8"); String str=new String(b,"utf-8"); String str1=new String(b,"gbk"); System.out.println(str); System.out.println(str1); } catch (UnsupportedEncodingException e) { e.printStackTrace(); }
运行上面的程序,你会发现,str 打印出来是正确,str1打印出来,是乱码的。
BufferedReader m_bufferedreader=new BufferedReader(new InputStreamReader(m_inputstream,encode)); StringBuffer m_stringbuffer=new StringBuffer(); while((one_line_string=m_bufferedreader.readLine())!=null){ m_stringbuffer.append(one_line_string);//缓存String
样使用字符流还缓存流来读入网络中的字符,还用stirngBufferer来做缓存,效率很高。
然后我说下这次项目里面碰到的一个问题:
我写一个网盘的客户端,要得到服务器发过来的HTTP报文中的报文头的文件,所以我要从报文中得到文件的名称,英文好还,中文就呵呵了,又乱码了,我和后台的人沟通,结果发现对的啊,也是无语了,后来查找了好久才看到,原来HTTP报文的问题:
HTTP报文的编码格式只能是ISO-8895-1,不能是别的,所以,HTTP服务器在发送报文的时候,把原来的编码的格式先转换成为了ISO-8895-1
就是这样的形式:
String s="计算机"; try { byte []b=s.getBytes("utf-8"); String str=new String(b,"iso-8895-1"); System.out.println(str); catch (UnsupportedEncodingException e) { e.printStackTrace();
所以,在不管你说server的编码格式utf-8,我这边也是用utf-8来解析的啊,都没用的,你拿到的就是一串乱码的东西,这样解决才是正确的:
byte []b=filename.getBytes("ISO-8859-1"); filename=new String(b,"utf-8");
也许这个例子不好理解,我做个比喻,服务器,先是把一个字符串(假设原来的是utf-8的编码格式的),然后服务器将这个字符串按照utf-8的标准,解码为二进制的字符串,再进行ISO-8859-1的编码,发送给客户端(但是,不管变成什么样子的二进制,原来的字符串想正确显示,就只有通过utf-8),所以,现在客户端就必须先将拿到的字符串先按照ISO-8859-1解码为原来的utf-8的二进制,再重新组合成为utf-8.方能正确显示
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/158071.html