java字符编码

来源:互联网 发布:centos 7 hadoop 安装 编辑:程序博客网 时间:2024/06/10 02:49

java出现乱码的原因一般来说有两个。一是编码和解码所使用的字符集不匹配。二是读取时读入的数量刚好把一个字符分开(对于字符而言)。在jvm中,不管在编译前java文件使用何种编码,在编译后成class后,他们都是一样的----Unicode编码具体说是UTF-16编码)表示。

1:简单的编码与解码示例:

public static void main(String[] args) throws UnsupportedEncodingException {
//获取本机的编码,得到GBK
System.out.println(System.getProperty("file.encoding"));//gbk
System.out.println(Charset.defaultCharset()); //gbk

String s = "中国";
byte[] bs = s.getBytes();//默认根据GBK进行编码
System.out.println(new String(bs));//默认根据系统的编码(GBK)解码,此处可以得到正确结果

byte[] bs1 = s.getBytes(Charset.forName("utf-8"));//根据utf-8进行编码
System.out.println(new String(bs1));//默认根据系统的编码(GBK)解码,所以出现乱码
System.out.println(new String(bs1,"utf-8"));//对应的根据utf-8进行解码,不会出现乱码

byte[] bs2 = s.getBytes();//默认根据GBK进行编码
System.out.println(new String(bs2,Charset.forName("utf-8")));//用utf-8解码,出现乱码
System.out.println(new String(bs2,"gbk"));//显示根据gbk进行解码,不会出现乱码
}


2:读文件时出现的乱码问题:

1):显示时乱码,主要问题出在:new String(byte[] data, String encoding);上

a.txt中测试内容为:wo是中国人!!!w哎人民加快递费撒娇fj监控端了撒啦id接口交罚款的说了句发京东网

首先,对a.txt编码为utf-8(另存为***),使用程序代码如下:(此时eclipse中编码为gbk)

File f = new File("F:/a.txt");
InputStream in = new FileInputStream(f);
byte[] buff = new byte[1024];
int len = 0;
while(-1!=(len = in.read(buff))){
System.out.println(new String(buff,0,len));
}

运行结果如下:出现乱码了

wo鏄腑鍥戒汉锛侊紒锛亀鍝庝汉姘戝姞蹇?璐规拻濞噁j鐩戞帶绔簡鎾掑暒id鎺ュ彛浜ょ綒娆剧殑璇翠簡鍙ュ彂浜笢缃?

出现乱码的原因就是a.txt中字符编码为utf-8,而eclipse为gbk,当调用new String(buff,0,len)会按“gbk"进行解码,二者不匹配,所以造成乱码。解决办法就是让二者匹配。解决办法如下:

1:将上述代码修改为如下:(使解码("utf-8"与编码相同))

File f = new File("F:/a.txt");
InputStream in = new FileInputStream(f);
byte[] buff = new byte[1024];
int len = 0;
while(-1!=(len = in.read(buff))){
System.out.println(new String(buff,0,len,"utf-8"));
}

2:修改a.txt的编码格式为gbk(ansi),或者修改eclipse的编码格式为utf-8.


2)字节流与字符流转换时出现乱码

测试环境为:a.txt的编码格式为utf-8,elipse的格式为gbk,代码如下:

BufferedReader br = new BufferedReader(new InputStreamReader(newFileInputStream(f)));
String line = null;
while((line = br.readLine())!=null){
System.out.println(line);
}

运行结果如下:(出现乱码

wo鏄腑鍥戒汉锛侊紒锛亀鍝庝汉姘戝姞蹇?璐规拻濞噁j鐩戞帶绔簡鎾掑暒id鎺ュ彛浜ょ綒娆剧殑璇翠簡鍙ュ彂浜笢缃?

原因很明显是二者编码格式不正确,解决办法是更改代码如下:

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f),"utf-8"));
String line = null;
while((line = br.readLine())!=null){
System.out.println(line);
}

3)按字节读取时读取个数造成的乱码问题

测试环境:a.txt的编码格式为utf-8,elipse的格式为utf-8,代码如下:

File f = new File("F:/a.txt");
InputStream in = new FileInputStream(f);
byte[] buff = new byte[33];
int len = 0;
while(-1!=(len = in.read(buff))){
System.out.println(new String(buff,0,len));
}

运行结果如下:

wo是中国人!!!w哎人民
加快递费撒娇fj监控端了�
��啦id接口交罚款的说了�
�发京东网

分析上述结果,可以发现是由于字节数组的长度为33造成的,在读取一个字符时,一次只读到了其中的一部分(一个字节),下次读取才读到另一部分,所以造成了乱码。

解决办法是最好采用字符流读取文本文件,且保证编码和解码的格式统一(第2类讨论的乱码问题)





0 0