字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文,字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。
字符编码(Character Encoding):是一套法则。是将我们自然的字符对应映射成计算机对应识别的数字对应,即就是把自然符号转换为计算机可以接受的数字系统的数,当然,这个数字是计算机的数字代码。
例如,在计算机中,使用一个字节的大小来表示固定的一个自然字符,假设,“m“这个字符对应的是 00010101,这两者之间是一一对应的关系,这样的话,“m”就完成了字符编码的过程,当然这只是一个假设的例子,不属于任何一种编码方案。
2. 有这样的一种说法:
编码:字符集编码和字符编码方案的一个组合 ,它可以将字符集中的字符,映射成字节序列。编码隐含着编码字符集和字符编码方案,从而也隐含着字符集。就是说是两层含义。在UTF-8这样的编码中,首先明确的是UTF-8中有自己可以表示的自然字符集,每种不同的编码方式所能表示的字符的多少范围是不一样的。第二层,这样丰富的自然字符都有规定序列的数字构成一一对应的关系,这些数字是以字节为单位存储表示的。
UTF-8是一种编码,它是Unicode编码字符集和UTF8编码方案的一个组合。GB2312也是一种编码,它的编码字符集就是编码的简体中文字符集,编码方案采用定长编码。
实践中经常混用编码字符集和编码这两个概念,这是因为大多数编码字符集都只有一种编码方案,这样的编码字符集(或者说编码)包括GB2312,GBK, ASCII, ISO8859-1等。
这里要注意的是,当编码字符集存在多种编码方案时,就有必要区分编码字符集和编码了,Unicode时一般是指编码字符集,说UTF-8UTF-16时才是指编码。
3. 常见字符编码
(1 )UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变。长度字符编码(定长码),也是一种前缀码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部份修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。UTF-8使用一至四个字节为每个字符编码:在处理经常会用到的ASCII字符方面非常有效。在处理扩展的拉丁字符集方面也不比UTF-16差。对于中文字符来说,比UTF-32要好。
( 2)Big5码是一套双字节字符集,使用了双八码存储方法,以两个字节来安放一个字。第一个字节称为"高位字节",第二个字节称为"低位字节"。"高位字节"使用了0x81-0xFE,"低位字节"使用了0x40-0x7E,及0xA1-0xFE,Big5属中文内码,一般使用繁体中文(正体中文)。在Big5的分区中
(3) Unicode(统一码、万国码、单一码、标准万国码)是业界的一种标准,它可以使电脑得以体现世界上数十种文字的系统。Unicode 是基于通用字符集(Universal Character Set)的标准来发展,并且同时也以书本的形式[1]对外发表。
(4)等等还有其他的不在啰嗦。
4. java应用程序中对字符的解码:
在音乐播放器中歌词部分的文件编码有对四种常见的编码格式 "GBK"、 "UTF-8"、"Unicode"、"UTF-16BE",每一种编码格式的区分在于写入文件头的信息不同。为了避免读取乱码的现象,在读取文本之前先读取文件头信息,以便做出正确的读取编码方式。
public static String codeString(File file) throws Exception
{
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(file));
int p = (bin.read() << 8) + bin.read();
String code = null;
Log.e("lyric","p="+p);
switch (p)
{
case 0xefbb:
code = "UTF-8";
break;
case 0xfffe:
code = "Unicode";
break;
case 0xfeff:
code = "UTF-16BE";
break;
default:
code = "GBK";
}
return code;
}
然后,以字符流的方式读取文本
InputStream in = new FileInputStream(file);
br = new BufferedReader(new InputStreamReader(in, codeString(file)));
StringBuilder sb = new StringBuilder();
String temp = null;
while ((temp = br.readLine()) != null) {
sb.append(temp).append("\n");
}
5. 出现字符乱码的时候进行字符转换:java层的转换
public class ChangeCharset {
/** 8 位 UTF转换格式 */
public static final String UTF_8 = "UTF-8";
/** 中文超大字符集 **/
public static final String GBK = "GBK";
/** 16 位 UTF转换格式,Big Endian(最低地址存放高位字节)字节顺序 */
public static final String UTF_16BE = "UTF-16BE";
/** 将字符编码转换成UTF-8 */
public String toUTF_8(String str) throws UnsupportedEncodingException {return this.changeCharset(str, UTF_8);}
/** 将字符编码转换成UTF-16BE */
public String toUTF_16BE(String str) throws UnsupportedEncodingException{return this.changeCharset(str, UTF_16BE);
}
/*
* 字符串编码转换的实现方法
* @param str 待转换的字符串
* @param newCharset 目标编码
*/
public String changeCharset(String str, String newCharset) throws UnsupportedEncodingException {
if(str != null) {
//用默认字符编码解码字符串。与系统相关,中文默认为GBK
byte[] bs = str.getBytes();
return new String(bs, newCharset); //用新的字符编码生成字符串
}
return null;
}
/**
* 字符串编码转换的实现方法
* @param str 待转换的字符串
* @param oldCharset 源字符集
* @param newCharset 目标字符集
*/
public String changeCharset(String str, String oldCharset, String newCharset)
throws UnsupportedEncodingException {
if(str != null) {
//用源字符编码解码字符串
byte[] bs = str.getBytes(oldCharset);
return new String(bs, newCharset);
}
return null;
}
public static void main(String[] args)throws UnsupportedEncodingException {
ChangeCharset test = new ChangeCharset();
String str = "This is a 中文的 String!";
System.out.println("str:" + str);
String utf8 = test.toUTF_8(str);
System.out.println("转换成UTF-8码:" + utf8);
String utf16be = test.toUTF_16BE(str);
System.out.println("转换成UTF-16BE码:" + utf16be);
gbk = test.changeCharset(utf16be, UTF_16BE, GBK);
System.out.println("再把UTF-16BE编码的字符转换成GBK码:" + gbk);
}
}
输出结果:
str:This is a 中文的 String!
转换成UTF-8码:This is a ????? String!
转换成UTF-16BE码:周楳?猠愠????瑲楮朡
再把UTF-16BE编码的字符转换成GBK码:This is a 中文的 String!
原理分析:
1、调用String的getByte方法对字符串进行解码,得到字符串的字节数组。
2、根据字节数组和新的字符编码构造一个新的String对象,得到的就是按照新的字符编码生成的字符串.