Java中String字符编码(CharSet)转换的相关问题

有用的资料

最近在字符编码上遇到一些问题,查阅了很多资料,有了一点领悟。以下是几个比较重要的资料:

《彻底搞懂字符编码》:

《深入分析 Java 中的中文编码问题》:

看了以上两篇文章,基本就能搞懂字符编码问题了。

下面是关于Java的字符编码问题的一个帖子,解释了Java的String中的字符存储问题:

个人小结:

在任何平台上,String中的char[]都是UTF-16类型的数组。String的所有操作都是在这个char[]上完成的。

Java的String是一个中间结果,可以通过getBytes(charset)函数得到指定编码的byte[]。

String.getBytes(charset)实际上是将UTF-16数组按照对应的charset编码为byte[]。网络程序中,将byte[]传输到其他平台,其他平台再用new String(byte[], charset)将byte[]转化为该平台本地的UTF-16字符串。

网上有一种转化字符串编码的方法:

String newString=new String(oldString.getBytes(oldCharSet),newCharSet),这种方式实际上没有任何意义,。下面简单解释一下。

以上转换的初衷通常是想在控制台(或文件)输出字符串。乱码是由于控制台(或文件)通常是GBK或UTF-8的,而String的char[]是UTF-16类型的。这时就需要使用 String.getBytes("GBK") 或者 String.getBytes("UTF-8") 得到byte[],然后使用 OutputStream.write(byte[]) 即可得到正确的输出。

另外,UTF-8通常比较省空间,一般通过String.getBytes("UTF-8")得到byte[],再进行网络传输。

示例程序

下面的程序简单的展示了这个过程:

import java.io.*;
public class TestCharSetConvert {	
	/*程序功能:
	 * 从文件中读入数据,以其他编码输出到其他文件中
	 */
	public static void main(String[] args){		
		//首先在程序目录下创建一个GBK编码的名为GBK.txt,里面可以包含任何汉字和英文等
		String inCharsetName="GBK";
		String[] outCharsetNames=new String[]{"GBK","GB2312","Unicode","UTF-8","UTF-16"};
		
		String content=readStringByStream(inCharsetName+".txt",inCharsetName);
		for(String outCharsetName: outCharsetNames){
			writeStringByStream(content,outCharsetName+".txt",outCharsetName);
		}
	}
	
	public static String readStringByStream(String inFilePath, String inCharsetName){
		try {
			FileInputStream fin=new FileInputStream(inFilePath);
			byte[] bytes=new byte[1024];
			int count=fin.read(bytes);
			String content=new String(bytes,0,count,inCharsetName);//解码为UTF-16字符串,inCharsetName必须与文件的字符编码一致,否则会失败或产生乱码
			System.out.format("read %s from %s with charset %s

",content,inFilePath,inCharsetName);
			fin.close();
			return content;
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	
	public static void writeStringByStream(String content, String outFilePath, String outCharsetName){
		try {
			FileOutputStream fout=new FileOutputStream(outFilePath);
			byte[] bytes=content.getBytes(outCharsetName);//将UTF-16字符串编码为指定字符集的字节流
			fout.write(bytes);			
			fout.close();			
			System.out.format("wrote %s to %s with charset %s
",content,outFilePath,outCharsetName);
		}
		catch (Exception e) {			
			e.printStackTrace();
		}
	}
}

以上程序使用了InputStream和OutputStream以字节流的方式输入输出。实际上Java的Reader和Writer已经封装了这个过程,可以使用它们进行面向字符和字符串的操作。
经验分享 程序员 微信小程序 职场和发展