如何理解java采用的是哪种编码Unicode编码

Java 编码中文问题系统透彻讲解 UNICODE GBK UTF-8 ISO-8859-1 之间的区别 | 基于实例代码分步讲解 一站式学习Java |
本视频是解读性视频,所以希望您已经看过了本知识点的内容,并且编写了相应的代码之后,带着疑问来观看,这样收获才多。 不建议一开始就观看视频
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器
如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)
走神了?退回10秒
计算机存放数据只能存放数字,所有的字符都会被转换为不同的数字。就像一个棋盘一样,不同的字,处于不同的位置,而不同的位置,有不同的数字编号。有的棋盘很小,只能放数字和英文有的大一点,还能放中文有的&足够&大,能够放下世界人民所使用的所有文字和符号如图所示,英文字符 A 能够放在所有的棋盘里,而且位置都差不多中文字符, 中文字符 中 能够放在后两种棋盘里,并且位置不一样,而且在小的那个棋盘里,就放不下中文
工作后经常接触的编码方式有如下几种:ISO-8859-1 ASCII 数字和西欧字母GBK GB2312 BIG5 中文UNICODE (统一码,万国码)其中ISO-8859-1 包含 ASCIIGB2312 是简体中文,BIG5是繁体中文,GBK同时包含简体和繁体以及日文。UNICODE 包括了所有的文字,无论中文,英文,藏文,法文,世界所有的文字都包含其中
根据前面的学习,我们了解到不同的编码方式对应不同的棋盘,而UNICODE因为要存放所有的数据,那么它的棋盘是最大的。 不仅如此,棋盘里每个数字都是很长的(4个字节),因为不仅要表示字母,还要表示汉字等。如果完全按照UNICODE的方式来存储数据,就会有很大的浪费。比如在ISO-8859-1中,a 字符对应的数字是0x61而UNICODE中对应的数字是 0x,倘若一篇文章大部分都是英文字母,那么按照UNICODE的方式进行数据保存就会消耗很多空间在这种情况下,就出现了UNICODE的各种减肥子编码, 比如UTF-8对数字和字母就使用一个字节,而对汉字就使用3个字节,从而达到了减肥还能保证健康的效果UTF-8,UTF-16和UTF-32 针对不同类型的数据有不同的减肥效果,一般说来UTF-8是比较常用的方式UTF-8,UTF-16和UTF-32 彼此的区别在此不作赘述,有兴趣的可以参考
写在.java源代码中的汉字,在执行之后,都会变成JVM中的字符。而这些中文字符采用的编码方式,都是使用UNICODE. &中&字对应的UNICODE是4E2D,所以在内存中,实际保存的数据就是十六进制的0x4E2D, 也就是十进制的20013。
public class TestStream {
public static void main(String[] args) {
String str = &中&;
public class TestStream {
public static void main(String[] args) {
String str = &中&;
以字符 中 为例,查看其在不同编码方式下的值是多少也即在不同的棋盘上的位置
import java.io.UnsupportedEncodingE
public class TestStream {
public static void main(String[] args) {
String str = &中&;
showCode(str);
private static void showCode(String str) {
String[] encodes = { &BIG5&, &GBK&, &GB2312&, &UTF-8&, &UTF-16&, &UTF-32& };
for (String encode : encodes) {
showCode(str, encode);
private static void showCode(String str, String encode) {
System.out.printf(&字符: \&%s\& 的在编码方式%s下的十六进制值是%n&, str, encode);
byte[] bs = str.getBytes(encode);
for (byte b : bs) {
int i = b&0
System.out.print(Integer.toHexString(i) + &\t&);
System.out.println();
System.out.println();
} catch (UnsupportedEncodingException e) {
System.out.printf(&UnsupportedEncodingException: %s编码方式无法解析字符%s\n&, encode, str);
接下来讲,字符在文件中的保存字符保存在文件中肯定也是以数字形式保存的,即对应在不同的棋盘上的不同的数字用记事本打开任意文本文件,并且另存为,就能够在编码这里看到一个下拉。ANSI
这个不是ASCII的意思,而是采用本地编码的意思。如果你是中文的操作系统,就会使GBK,如果是英文的就会是ISO-8859-1Unicode UNICODE原生的编码方式Unicode big endian 另一个 UNICODE编码方式UTF-8 最常见的UTF-8编码方式,数字和字母用一个字节, 汉字用3个字节。
eclipse也有类似的编码方式,右键任意文本文件,点击最下面的&property&就可以看到Text file encoding也有ISO-8859-1,GBK,UTF-8等等选项。其他的US-ASCII,UTF-16,UTF-16BE,UTF-16LE不常用。
为了能够正确的读取中文内容1. 必须了解文本是以哪种编码方式保存字符的2. 使用字节流读取了文本后,再使用对应的编码方式去识别这些数字,得到正确的字符如本例,一个文件中的内容是字符中,编码方式是GBK,那么读出来的数据一定是D6D0。再使用GBK编码方式识别D6D0,就能正确的得到字符中注: 在GBK的棋盘上找到的中字后,JVM会自动找到中在UNICODE这个棋盘上对应的数字,并且以。
import java.io.F
import java.io.FileInputS
import java.io.IOE
public class TestStream {
public static void main(String[] args) {
File f = new File(&E:\\project\\j2se\\src\\test.txt&);
try (FileInputStream fis = new FileInputStream(f);) {
byte[] all = new byte[(int) f.length()];
fis.read(all);
//文件中读出来的数据是
System.out.println(&文件中读出来的数据是:&);
for (byte b : all)
int i = b&0x000000
//只取16进制的后两位
System.out.println(Integer.toHexString(i));
System.out.println(&把这个数字,放在GBK的棋盘上去:&);
String str = new String(all,&GBK&);
System.out.println(str);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
FileReader得到的是字符,所以一定是已经把字节根据某种编码识别成了字符了而FileReader使用的编码方式是Charset.defaultCharset()的返回值,如果是中文的操作系统,就是GBKFileReader是不能手动设置编码方式的,为了使用其他的编码方式,只能使用InputStreamReader来代替,像这样:new InputStreamReader(new FileInputStream(f),Charset.forName(&UTF-8&)); 在本例中,用记事本另存为UTF-8格式,然后用UTF-8就能识别对应的中文了。解释: 为什么中字前面有一个?如果是使用记事本另存为UTF-8的格式,那么在第一个字节有一个标示符,叫做BOM用来标志这个文件时用UTF-8来编码的。
import java.io.F
import java.io.FileInputS
import java.io.FileNotFoundE
import java.io.FileR
import java.io.IOE
import java.io.InputStreamR
import java.io.UnsupportedEncodingE
import java.nio.charset.C
public class TestStream {
public static void main(String[] args) throws UnsupportedEncodingException, FileNotFoundException {
File f = new File(&E:\\project\\j2se\\src\\test.txt&);
System.out.println(&默认编码方式:&+Charset.defaultCharset());
//FileReader得到的是字符,所以一定是已经把字节根据某种编码识别成了字符了
//而FileReader使用的编码方式是Charset.defaultCharset()的返回值,如果是中文的操作系统,就是GBK
try (FileReader fr = new FileReader(f)) {
char[] cs = new char[(int) f.length()];
fr.read(cs);
System.out.printf(&FileReader会使用默认的编码方式%s,识别出来的字符是:%n&,Charset.defaultCharset());
System.out.println(new String(cs));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
//FileReader是不能手动设置编码方式的,为了使用其他的编码方式,只能使用InputStreamReader来代替
//并且使用new InputStreamReader(new FileInputStream(f),Charset.forName(&UTF-8&)); 这样的形式
try (InputStreamReader isr = new InputStreamReader(new FileInputStream(f),Charset.forName(&UTF-8&))) {
char[] cs = new char[(int) f.length()];
isr.read(cs);
System.out.printf(&InputStreamReader 指定编码方式UTF-8,识别出来的字符是:%n&);
System.out.println(new String(cs));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
&姿势不正确,事倍功半。
找出 E5 B1 8C 这3个十六进制对应UTF-8编码的汉字
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
本视频是解读性视频,所以希望您已经看过了本答案的内容,带着疑问来观看,这样收获才多。 不建议一开始就观看视频
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器
如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)
走神了?退回10秒
import java.io.UnsupportedEncodingE
public class TestStream {
public static void main(String[] args) throws UnsupportedEncodingException {
找出 E5 B1 8C 这3个十六进制对应UTF-8编码的汉字
byte[] bs = new byte[3];
bs[0] = (byte) 0xE5;
bs[1] = (byte) 0xB1;
bs[2] = (byte) 0x8C;
String str
=new String(bs,&UTF-8&);
System.out.println(&E5 B1 8C 对应的字符是:&+str);
import java.io.UnsupportedEncodingE
public class TestStream {
public static void main(String[] args) throws UnsupportedEncodingException {
找出 E5 B1 8C 这3个十六进制对应UTF-8编码的汉字
byte[] bs = new byte[3];
bs[0] = (byte) 0xE5;
bs[1] = (byte) 0xB1;
bs[2] = (byte) 0x8C;
String str
=new String(bs,&UTF-8&);
System.out.println(&E5 B1 8C 对应的字符是:&+str);
&姿势不正确,事倍功半。
如果用记事本根据UTF-8编码保存汉字就会在最前面生成一段标示符,这个标示符用于表示该文件是使用UTF-8编码的。找出这段标示符对应的十六进制,并且开发一个方法,自动去除这段标示符
在查看答案前,尽量先自己完成,碰到问题再来查看答案,收获会更多
本视频是解读性视频,所以希望您已经看过了本答案的内容,带着疑问来观看,这样收获才多。 不建议一开始就观看视频
本视频采用html5方式播放,如无法正常播放,请将浏览器升级至最新版本,推荐火狐,chrome,360浏览器
如果装有迅雷,播放视频呈现直接下载状态,请调整 迅雷系统设置-基本设置-启动-监视全部浏览器 (去掉这个选项)
走神了?退回10秒
import java.io.F
import java.io.FileInputS
import java.io.IOE
import java.util.A
public class TestStream {
public static void main(String[] args) {
File f = new File(&E:\\project\\j2se\\src\\test.txt&);
try (FileInputStream fis = new FileInputStream(f);) {
byte[] all = new byte[(int) f.length()];
fis.read(all);
System.out.println(&首先确认按照UTF-8识别出来有?&);
String str = new String(all,&UTF-8&);
System.out.println(str);
System.out.println(&根据前面的所学,知道'中'字对应的UTF-8编码是:e4 b8 ad&);
System.out.println(&打印出文件里所有的数据的16进制是:&);
for (byte b : all) {
int i = b&0
System.out.print(Integer.toHexString(i)+ & &);
System.out.println();
System.out.println(&通过观察法得出 UTF-8的 BOM 是 ef bb bf&);
byte[] bom = new byte[3];
bom[0] = (byte) 0
bom[1] = (byte) 0
bom[2] = (byte) 0
byte[] fileContentWithoutBOM= removeBom(all,bom);
System.out.println(&去掉了BOM之后的数据的16进制是:&);
for (byte b : fileContentWithoutBOM) {
int i = b&0
System.out.print(Integer.toHexString(i)+ & &);
System.out.println();
System.out.println(&对应的字符串就没有问号了:&);
String strWithoutBOM=new String(fileContentWithoutBOM,&UTF-8&);
System.out.println(strWithoutBOM);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
private static byte[] removeBom(byte[] all, byte[] bom) {
return Arrays.copyOfRange(all, bom.length, all.length);
把你的代码复制到下面区域。 如果在线比较不好用,请使用客户端比较软件:
代码高亮插件双击即可选中,不过部分同学反应,通过代码高亮插件复制的代码无法在IDEA里正常显示,这里提供TEXTAREA的方式,方便复制,谢谢
根据练习目标尽量自己实现代码效果,期间会碰到疑问,难题,和自己不懂的地方,这些都是必要的过程
完成过程中,碰到无法解决的问题,带着疑问,查看答案,分析答案的解决思路
依然有不明白的地方,点开视频讲解,带着疑问,听视频讲解有问题的部分
理解后,再从头做一遍,把有疑问的地方都捋清楚
最后再总结一边,总结思路,总结解决办法,以后遇到类似的问题,怎么处理
把这时的想法,思路,研究都记录下来,等全部学完了,再回过头来巩固和理解,学习效果就会很好,知识点掌握得也牢固
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
答案时间:
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
答案时间:
答案时间:
请至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到
提问之前请
欢度国庆,全场五折,优惠码:HAPPY10
可用于全站通
有效期9.27- 9.29博客分类:
故事是这样的,那天和同事讨论上传txt文件,如何能防止文件乱码,其间引出了如下问题:
& 1.如何防止上传文件乱码(无论任何语言).
& 2.用byte array&utf-8构造string,java如何判断几个byte一个中文字符.
& 3.utf-8和unicode的区别.
& 4.一个utf-8 string有几个char,几个byte?
& 随着这些问题的解决,对java和unicode,utf-8之间的关系有了更深层的认识.
如何防止上传文件乱码(无论任何语言).
& 为了支持i18n,我们必须要求上传文件的编码是utf-8或unicode,否则无法实现全语言的支持.utf-8的文件开头会有EF BB BF标志。
用byte array&utf-8构造string,java如何判断几个byte一个中文字符.
& 因utf-8是变长编码,所以有些字符会是一个字节(如:ascii),有些会是3个(如:中文),
但在用byte array构造string时,jvm是如何判断以几个字节为一组来构造呢?
& 原来utf-8编码本身有标志可以判断,每个字符的第一个byte前几位是标示位10*,110*,*,其中1的个数代表这个字符有几个字节。
utf-8和unicode的区别.
& unicode是定长编码,每个字符都是2 byte,所以在存储ascii时会浪费一个byte的空间。而utf-8是变长unicode编码,在unicode编码基础上进行变长,在存储ascii时只占用一个byte.存储中文时占用3 byte.
一个utf-8 string有几个char,几个byte?
String s = "中国";
byte[] b = s.getBytes("utf-8");
String s_utf8 = new String(b,"utf-8");
System.out.println(s_utf8.getBytes("utf-8").length);
System.out.println(s_utf8.toCharArray().length);
结果是:
&&& 6
&&& 2
按照上面的结果看好像一个char是3 byte,但java中一个char是2 byte,为什么?
其实java中无论什么字符集string都会以unicode编码来存储,所以每个char都是一个
unicode编码占两个byte。
import java.io.UnsupportedEncodingE
public class TestUtf8File {
* @param args
* @throws UnsupportedEncodingException
public static void main(String[] args) throws UnsupportedEncodingException {
String s = "中国人";
byte[] b = s.getBytes("utf-8");
String s_utf8 = new String(b,"utf-8");
System.out.println(s_utf8.getBytes("utf-8").length);
System.out.println("utf-8 bytes:");
printByteArray(s_utf8.getBytes("utf-8"));
System.out.println("chars:");
printCharArray(s_utf8.toCharArray());
byte[] unicodeb= s.getBytes("unicode");
String s_unidode = new String(unicodeb,"unicode");
System.out.println("unicode bytes:");
printByteArray(s_unidode.getBytes("unicode"));
private static void printByteArray(byte[] b){
for(int i = 0;i & b. i++){
System.out.println((Integer.toString(b[i],16)));
private static void printCharArray(char[] c){
for(int i = 0;i & c. i++){
System.out.println(Integer.toString((byte)(c[i]&&8),16));
System.out.println(Integer.toString((byte)(c[i]&0xff),16));
output:
9
utf-8 bytes:
-1c
-48
-53
-1b
-65
-43
-1c
-46
-46
chars:
4e
2d
56
-3
4e
-46
unicode bytes:
-2
-1
4e
2d
56
-3
4e
-46
-2 -1(FE FF)是unicode big endian标志
fe ff:big endian
ff fe: no big endian
浏览 12572
博主,我想知道那个& System.out.println((Integer.toString(b[i],16)))中的16是什么意思?System.out.println(Integer.toString((byte)(c[i]&&8),16));& &&&&& System.out.println(Integer.toString((byte)(c[i]&0xff),16)); 中的&&8和0xff是什么意思,谢谢。。。char类型占两个字节,c[i]&&8右移八位取第一个字节的数据,c[i]&0xff这个是取第二个字节的。
浏览: 51954 次
来自: 北京
为什么“中国人”用unicode编码占8个字节?
&div class=&quote_title ...
讲的太好了,学习一下
博主,我想知道那个
System.out.println(( ...
楼主说的非常好, 代码也很适合研究
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'1673人阅读
字符编码(5)
在JVM中、在内存中、在代码里声明的每一个char、String类型的变量中字符以unicode格式存在。
为什么Java中使用unicode字符集?看文本文,一定会找到答案。
还是得从ASCII码说起
说到字符编码,不得不说ASCII码的简史。计算机一开始发明的时候是用来解决数字计算的问题,后来人们发现,计算机还可以做更多的事,例如文本处理。但由于计算机只识“数”,因此人们必须告诉计算机哪个数字来代表哪个特定字符,例如65代表字母‘A’,66代表字母‘B’,以此类推。但是计算机之间字符-数字的对应关系必须得一致,否则就会造成同一段数字在不同计算机上显示出来的字符不一样。因此美国国家标准协会ANSI制定了一个标准,规定了常用字符的集合以及每个字符对应的编号,这就是ASCII字符集(Character Set),也称ASCII码。
那时候的字符编解码系统非常简单,就是简单的查表过程。例如将字符序列编码为二进制流写入存储设备,只需要在ASCII字符集中依次找到字符对应的字节,然后直接将该字节写入存储设备即可。解码二进制流的过程也是类似。
OEM字符集的衍生
当计算机开始发展起来的时候,人们逐渐发现,ASCII字符集里那可怜的128个字符已经不能再满足他们的需求了。人们就在想,一个字节能够表示的数字(编号)有256个,而ASCII字符只用到了0x00~0x7F,也就是占用了前128个,后面128个数字不用白不用,因此很多人打起了后面这128个数字的主意。可是问题在于,很多人同时有这样的想法,但是大家对于0x80-0xFF这后面的128个数字分别对应什么样的字符,却有各自的想法。这就导致了当时销往世界各地的机器上出现了大量各式各样的OEM字符集。
大家对于0x00~0x7F这个范围的解释基本是相同的,而对于后半部分0x80~0xFF的解释却不一定相同。甚至有时候同样的字符在不同OEM字符集中对应的字节也是不同的。
不同的OEM字符集导致人们无法跨机器交流各种文档。例如职员甲发了一封简历résumés给职员乙,结果职员乙看到的却是r?sum?s,因为é字符在职员甲机器上的OEM字符集中对应的字节是0x82,而在职员乙的机器上,由于使用的OEM字符集不同,对0x82字节解码后得到的字符却是?。
多字节字符集(MBCS)和中文字符集
上面我们提到的字符集都是基于单字节编码,也就是说,一个字节翻译成一个字符。这对于拉丁语系国家来说可能没有什么问题,因为他们通过扩展第8个比特,就可以得到256个字符了,足够用了。但是对于亚洲国家来说,256个字符是远远不够用的。因此这些国家的人为了用上电脑,又要保持和ASCII字符集的兼容,就发明了多字节编码方式,相应的字符集就称为多字节字符集。例如中国使用的就是双字节字符集编码(DBCS,Double Byte CharacterSet)。
对于单字节字符集来说,代码页中只需要有一张码表即可,上面记录着256个数字代表的字符。程序只需要做简单的查表操作就可以完成编解码的过程。
“代码页是字符集编码的具体实现,你可以把他理解为一张“字符-字节”映射表,通过查表实现“字符-字节”的翻译。下面会有更详细的描述。”
而对于多字节字符集,代码页中通常会有很多码表。那么程序怎么知道该使用哪张码表去解码二进制流呢?答案是,根据第一个字节来选择不同的码表进行解析。
例如目前最常用的中文字符集GB2312,涵盖了所有简体字符以及一部分其他字符;GBK(K代表扩展的意思)则在GB2312的基础上加入了对繁体字符等其他非简体字符(GB18030字符集不是双字节字符集,我们在讲Unicode的时候会提到)。这两个字符集的字符都是使用1-2个字节来表示。Windows系统采用936代码页来实现对GBK字符集的编解码。在解析字节流的时候,如果遇到字节的最高位是0的话,那么就使用936代码页中的第1张码表进行解码,这就和单字节字符集的编解码方式一致了。
当字节的高位是1的时候,确切的说,当第一个字节位于0x81–0xFE之间时,根据第一个字节不同找到代码页中的相应的码表,例如当第一个字节是0x81,那么对应936中的下面这张码表:
按照936代码页的码表,当程序遇到连续字节流0x81 0x40的时候,就会解码为“丂”字符。
ANSI标准、国家标准、ISO标准
不同ASCII衍生字符集的出现,让文档交流变得非常困难,因此各种组织都陆续进行了标准化流程。例如美国ANSI组织制定了ANSI标准字符编码(注意,我们现在通常说到ANSI编码,通常指的是平台的默认编码,例如英文操作系统中是ISO-8859-1,中文系统是GBK),ISO组织制定的各种ISO标准字符编码,还有各国也会制定一些国家标准字符集,例如中国的GBK,GB2312和GB18030。
操作系统在发布的时候,通常会往机器里预装这些标准的字符集还有平台专用的字符集,这样只要你的文档是使用标准字符集编写的,通用性就比较高了。例如你用GB2312字符集编写的文档,在中国大陆内的任何机器上都能正确显示。同时,我们也可以在一台机器上阅读多个国家不同语言的文档了,前提是本机必须安装该文档使用的字符集。
Unicode的出现
虽然通过使用不同字符集,我们可以在一台机器上查阅不同语言的文档,但是我们仍然无法解决一个问题:在一份文档中显示所有字符。为了解决这个问题,我们需要一个全人类达成共识的巨大的字符集,这就是Unicode字符集。
Unicode字符集概述
Unicode字符集涵盖了目前人类使用的所有字符,并为每个字符进行统一编号,分配唯一的字符码(Code Point)。Unicode字符集将所有字符按照使用上的频繁度划分为17个层面(Plane),每个层面上有216=65536个字符码空间。
其中第0个层面BMP,基本涵盖了当今世界用到的所有字符。其他的层面要么是用来表示一些远古时期的文字,要么是留作扩展。我们平常用到的Unicode字符,一般都是位于BMP层面上的。目前Unicode字符集中尚有大量字符空间未使用。
编码系统的变化
在Unicode出现之前,所有的字符集都是和具体编码方案绑定在一起的,都是直接将字符和最终字节流绑定死了,例如ASCII编码系统规定使用7比特来编码ASCII字符集;GB2312以及GBK字符集,限定了使用最多2个字节来编码所有字符,并且规定了字节序。这样的编码系统通常用简单的查表,也就是通过代码页就可以直接将字符映射为存储设备上的字节流了。例如下面这个例子:
这种方式的缺点在于,字符和字节流之间耦合得太紧密了,从而限定了字符集的扩展能力。假设以后火星人入住地球了,要往现有字符集中加入火星文就变得很难甚至不可能了,而且很容易破坏现有的编码规则。
因此Unicode在设计上考虑到了这一点,将字符集和字符编码方案分离开。
也就是说,虽然每个字符在Unicode字符集中都能找到唯一确定的编号(字符码,又称Unicode码),但是决定最终字节流的却是具体的字符编码。例如同样是对Unicode字符“A”进行编码,UTF-8字符编码得到的字节流是0x41,而UTF-16(大端模式)得到的是0x00 0x41。
Unicode相关的常见问题
Unicode是两个字节吗?
Unicode只是定义了一个庞大的、全球通用的字符集,并为每个字符规定了唯一确定的编号,具体存储为什么样的字节流,取决于字符编码方案。推荐的Unicode编码是UTF-16和UTF-8。
Unicode编码和以前的字符集编码有什么区别?
早期字符编码、字符集和代码页等概念都是表达同一个意思。例如GB2312字符集、GB2312编码,936代码页,实际上说的是同个东西。
但是对于Unicode则不同,Unicode字符集只是定义了字符的集合和唯一编号,Unicode编码,则是对UTF-8、UCS-2/UTF-16等具体编码方案的统称而已,并不是具体的编码方案。所以当需要用到字符编码的时候,你可以写gb2312,codepage936,utf-8,utf-16,但请不要写unicode(看过别人在网页的meta标签里头写charset=unicode,有感而发)。
乱码指的是程序显示出来的字符文本无法用任何语言去解读。一般情况下会包含大量或者?。乱码问题是所有计算机用户或多或少会遇到的问题。造成乱码的原因就是因为使用了错误的字符编码去解码字节流,因此当我们在思考任何跟文本显示有关的问题时,请时刻保持清醒:当前使用的字符编码是什么。只有这样,我们才能正确分析和处理乱码问题。
例如最常见的网页乱码问题。如果你是网站技术人员,遇到这样的问题,需要检查以下原因:
服务器返回的响应头Content-Type没有指明字符编码 网页内是否使用META HTTP-EQUIV标签指定了字符编码 网页文件本身存储时使用的字符编码和网页声明的字符编码是否一致
关于乱码中出现?或者?,这里需要额外提一下,当程序使用特定字符编码解析字节流的时候,一旦遇到无法解析的字节流时,就会用或者?来替代。因此,一旦你最终解析得到的文本包含这样的字符,而你又无法得到原始字节流的时候,说明正确的信息已经彻底丢失了,尝试任何字符编码都无法从这样的字符文本中还原出正确的信息来。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:187490次
积分:4685
积分:4685
排名:第6596名
原创:276篇
转载:43篇
评论:15条
(7)(4)(12)(32)(3)(7)(4)(3)(14)(10)(7)(6)(5)(7)(3)(6)(10)(10)(4)(2)(5)(9)(19)(10)(4)(7)(26)(51)(8)(19)(12)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'

我要回帖

更多关于 java如何base64编码 的文章

 

随机推荐