基础知识
字节和字符
字节(byte):一个八位的存储单元,取值范围一定是0~255;
字符(character):就是一个语言上的符号,"中"字就是一个字符。
字符所占的大小由其编码方式解决,比如"中"在UTF-8中占3个字节(0xE4A8AD),而在GBK中,则占两个字节(0xD6D0)。
字符集和编码
字符集:字符的集合,像Unicode字符集,目标就是收纳了这个世界上所有语言的文字、符号等;
字符编码:注意,字符集只是规定了有哪些字符,而最终决定采用哪些字符,每一个字符用多个字节表示等问题,
则是由编码来决定的。像Unicode字符集的编码方式有很多,
诸如UTF-8、UFT-16、UTF-32等。字符集和字符编码是分开的概念,
但有时候称呼上会有些模糊,我们经常笼统地称这些Unicode字符集的编码为Unicode编码。
内码:操作系统内部的字符编码。像早期的DOS采用的是ASCII,而现在的操作系统大把采用Unicode编码。
编码简史
先了解一下编码的历史,才能知道为什么要编码。
计算机对多语言的支持,大致为分以下三个阶段:
阶段一:ASCII时代。计算机是DOS时代的计算内码是ASCII码,ASCII的表示范围就是0到127那几个符号,
这意味着,DOS时代的计算机只能显示英文,而无法支持其他语言。
由于英文系国家开创了并继续主导了计算机的世界,他们自然而然地认为全世界的文字用8个字节表示足矣。
阶段二:ANSI时代。由于上述原因,像我们这些非英文系的国家的为了显示自家的文字,
不得不一开始就得面对字符编码的问题,不同国家不同地区都创建了自己的编码标准。
像中国大陆是GB2312及后来的GBK,台湾是BIG5,日本是JIS。
ASCII字符集,以及这些由此派生并兼容的字符集称为ANSI字符集。
阶段三:Unicode时代。为了和谐而出现,相较于以上两个阶段,这个时代称为国际化时代,
适应了跨平台、跨语言之间交换信息的需求。
package edu.fjut.charset;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
/*在计算机世界里,任何的文字都是以指定的编码方式存在的,在JAVA程序开发中,
*最常见的编码有一下几种:ISO8859-1、GBK/GB2312、Unicode、UTF
*ISO8859-1:此编码属于单字节编码,最多只能表示0-255的字符范围,主要用于英文
*GBK/GB2312:中文的国标编码、专门用来表示汉字,是双字节编码.GB2312只能表示简体
*unicode:java中就是使用此编码方式,也是最标准的一种编码,是使用16进制表示的编码.
* 但此编码不兼容ISO8859-1编码
*UTF:由于Unicode不支持ISO8859-1编码,而且容易占用更多的空间,而且对于英文字母也
* 需要使用两个字节编码,这样使用Unicode不便于传输和存储,因此产生了UTF编码,
* UTF编码兼容了ISO8859-1编码,可以用来表示所有的语言字符.
* UTF是 Unicode Translation Format,即把Unicode转做某种格式的意思。
*/
public class CharsetDemo {
//乱码产生的根本原因是:字符编码不统一造成的
public static void main(String[] args) throws Exception{
//因为现在的本机环境是中文环境,所以是使用GBK编码
System.out.println("系统默认编码:"+System.getProperty("file.encoding"));//GBK
File file=new File("d:"+File.separator+"javase"+File.separator+"code.txt");
OutputStream out=new FileOutputStream(file);//实例化输出流
byte []b="中国,你好".getBytes("ISO8859-1");//转码操作,可以指定要的字符编码
out.write(b);//保存,打开文件后,凡是中文的全部变成?????,因为编码不一致
//改成支持中文的编码就行了
out.close();//关闭
}
}