unicode是一种“编码”,所谓编码就是一个编号(数字)到字符的一种映射关系,就仅仅是一种一对一的映射而已,可以理解成一个很大的对应表格
GBK、
UTF-8是一种“编码格式”,是用来序列化或存储1中提到的那个“编号(数字)”的一种“格式”;GBK和UTF-8都是用来序列化或存储
unicode编码的数据的,但是分别是2种不同的格式;
他们俩除了格式不一样之外,他们所关心的unicode编码范围也不一样,utf-8考虑了很多种不同国家的字符,涵盖整个unicode码表,所以其存
储一个字符的编码的时候,使用的字节长度也从1字节到4字节不等;而GBK只考虑中文——在unicode中的一小部分——的字符,的编码,所以它算好了
只要2个字节就能涵盖到绝大多数常用中文(2个字节能表示6w多种字符),所以它存储一个字符的时候,所用的字节长度是固定的;
上述2个概念不懂的请马上google,下面不再赘述;我下面说说这个问题本身的问题在哪里
首
先java的string使用的编码是unicode,但是,当string存在于内存中时(也就是当程序运行时、你在代码中用string类型的引用对
它进行 *** 作时、也就是string没有被存在文件中且也没有在网络中传输(序列化)时),是“只有编码而没有编码格式的”,所以java程序中的任何
String对象,说它是gbk还是utf-8都是错的,gbk和utf-8是编码格式而不是编码,String在内存中不需要“编码格式”(记住编码格
式是在存文件或序列化的时候使用的), 它只是一个unicode的字符串而已
所以java里面String是不带编码格式的,而
StringtoByteArray(charsetName)得到的byteArray是带编码格式的,格式就是你传入的
'charsetName',我们不妨把toByteArray的这个过程叫做“编码”;另外,new String(byte[],
charsetName)是把一个byte数组(带编码格式)以charsetName指定的编码格式翻译为一个不带编码格式的String对象,我们不
妨把这个过程叫“解码”
那么根据我揣测提问者的意图,可能有2种问法是他真正想问的:
第一,如何把一个被错误地当作是gbk格式存储的utf-8格式的文件里面读出来的一段乱码字符串还原回去(也就是说本来二进制数据是utf-8的,你用gbk来解码它,得到的字符串是乱码,现在想要还原回去)
第二种,如何把一个gbk文件转化为utf-8文件
如果是第一种意图那就:
public static void main(String args) throws Throwable {
String errStr = "errStr";
Systemoutprintln(recover(errStr));
}
public static String recover(String str) throws Throwable {
return new String(strgetBytes("GBK"), "UTF-8");
}
其中errStr就是乱码字符串,按照相反的顺序在编码(用gbk)、解码(用utf-8)回去,就能得到正确的字符串(其实不保证所有情况均能正确还原,只能说大部分都能,要看你在乱码过程中是否有数据被丢失)
如果是第二种意图,那就用InputStream以gbk格式将文件读到内存里(表示为String),再将这个String以UTF-8编码写入目标文件里,具体请参考InputStream/OutputStream的api通常是GB2312或者GB18032因为在默认情况下你输入的中文都是GB2312的在环境也是GB2312才能正确显示,你吧工程装换为UTF-8后只是环境变了文字还都是GB2312的所以会乱码。。。你得重新输入文字或者把环境改回GB2312你要把代码转编码的话自己动手改改就好了,要是文本转编码的话可以自己写个程序跑一遍应该就好了,这个你自己改改看可以用不?packageutil;importjavaioBufferedReader;importjavaioBufferedWriter;importjavaioFile;importjavaioFileInputStream;importjavaioFileNotFoundException;importjavaioFileOutputStream;importjavaioIOException;importjavaioInputStreamReader;importjavaioOutputStreamWriter;importjavaioUnsupportedEncodingException;/@authorlouisversion2010-8-8/publicclassChangeEncode{Stringdatasorce="G:\\main\\more";StringtagString="G:\\main\\more_2312";//转换文本文档的编码格式。publicChangeEncode(){//要读的原文件。Filesource=newFile(datasorce);File[]file=sourcelistFiles();Systemoutprintln(file[0]getName());FileInputStreamfileInputStream=null;InputStreamReaderinputStreamReader=null;BufferedReaderbufferedReader=null;//要写入的新文件。Filetag=newFile(tagString);String[]nameString=sourcelist();FileOutputStreamfileOutputStream=null;OutputStreamWriteroutputStreamWriter=null;BufferedWriterbufferedWriter=null;for(inti=0;i1、编码是为了正常显示文字内容而设置的,要想正常的显示文字内容,文字本身的编码格式必须与显示端的编码格式一致;
2、国内常用的中文编码格式是:GBK(中国标准,包含全部中文字符,以双字节来显示中文和英文字符)、UTF-8(国际编码,包含世界各个国家的文字字符,通用性强);
3、浏览器用GBK编码显示乱码,说明浏览器所用的编码格式(GBK)与要显示的内容的编码格式不同,即要显示内容不是用GBK编码方式生成的,两者编码格式一致才能正常显示,否则就显示乱码。package url; import javaioUnsupportedEncodingException; public class GBK2UTF8 { public static void main(String[] args) throws UnsupportedEncodingException { String chinese = 中文;java内部编码 String gbkChinese = new String(chinesegetBytes(GBK),ISO-8859-1);转换成gbk编码 String unicodeChinese = new String(gbkChinesegetBytes(ISO-8859-1),GBK);java内部编码 Systemoutprintln(unicodeChinese);中文 String utf8Chinese = new String(unicodeChinesegetBytes(UTF-8),ISO-8859-1);utf--8编码 Systemoutprintln(utf8Chinese);乱码 unicodeChinese = new String(utf8ChinesegetBytes(ISO-8859-1),UTF-8);java内部编码 Systemoutprintln(unicodeChinese);中文 } }我先解释一下我对你的问题的理解
:
你的问题有点笼统
可以这么理解两个意思
:
一
,你是想吧一个gbk编码的字符串用utf-8格式来编码
String
s
=
new
String
("全国"getBytes("GBK"),"GBK");
虽然这个时候的s是GBK编码的
但是s还是中文字符的
所以
上面这位同胞用
new(sgetBytes("GBK"),"UTF-8")的方式肯定是错的
应该用
String
s1
=
new
String
(sgetBytes("UTF-8"),"UTF-8")
这样s1就是UTF-8编码的字符串了
二,如果是遇见乱码问题
比如
String
s
=
new
String
("全国"getBytes("GBK"),"GBK");
这样的s就是gbk编码的
现在你要把GBK格式的编码用UTF-8去编码
肯定就会出现乱码
String
s2
=
new
String(sgetBytes("GBK"),"UTF-8");
这个s2肯定是乱码的
而且这样就根本解不出来了
系统出现的乱码显示的时候才会出现编码错误
所以
一般出现乱码
只要把输入流换个编码解析一下就ok了
还有什么不明白
可以问我首先理解java的字符概念
java中字符串是字符的序列,虚拟机内部的字符都是16位的unicode字符,等价于C++中的WCHAR,也是为了实现虚拟机方便
WCHAR叫做宽字符,对应的MuitiChar叫做多字符,这种多字符中字符的位数不唯一
GBK 和 UTF8 是多字符的不同编码形式
s=new String(sgetBytes("gbk"),"utf-8");
的意思是:
byte[] bytes=sgetBytes("gbk");
s=new String(bytes,"utf-8");
第一句是将s对应的gbk编码转出来,形成一个字节流
第二句是将这个字节流按照utf-8编码转为java字符串,因此相当于将gbk编码的字节流当做utf-8来使用,这样在中文中会出现乱码
你的问题是,接口返回的已经是utf-8 所以它必须是byte[] 流,如果是字符串的话就不好办了
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)