java中GBK与UTF-8编码的转换

本文探讨了Java中GBK与UTF-8编码转换的问题,包括字符编码问题的由来,如何在Windows和Linux环境下处理源文件编码,以及如何在Java中实现文件编码的转换。此外,还介绍了如何利用cpdetector库来判断文件的编码格式,以解决无BOM的UTF-8文件判断难题。
摘要由CSDN通过智能技术生成


java编码中常遇到的编码转换问题,主要是UTF-8、unicode与GBK编码之间的转换。

经常需要转换的主要原因是:中文编码的问题,如果编解码不对应,经常遇到令人烦躁的乱码问题。究其原因是:在unicode系列编码和GBK系列编码中,同一个中文的字符对应的编码不同。

在java中字符默认是unicode编码的方式存储。

java源文件中中文字符的编码的问题

windows系统默认的编码为:gbk.

命令行编译java代码不用-encoding指定编码选项时,会默认按照GBK编码编译,如果源文件编码不是GBK编码,编译(可能)将产生错误:xxx编码不可映射的字符集。

linux/unix系统默认的编码为:utf-8.

命令行编译java代码不用-encoding指定编码选项时,会默认按照utf-8编码编译,如果源文件编码不是utf-8编码,编译(可能)将产生错误:xxx编码不可映射的字符集。

针对以上问题,可在编译时指定和源文件一致的编码即可,输出中文将正常,将不受操作系统默认的编码的影响。

eg: windows下utf-8编码的Test.java代码,利用下面的编译指令可通过编译,且中文在终端输出正常。


javac Test.java -encoding utf-8

java Test

UTF-8和GBK格式的文件相互转换

UTF-8和GBK格式的数据不能直接转换,需要先转化为unicode编码,再进行转换。

unicode的码表官网:http://www.unicode.org/charts/

unicode的编码范围和各国语言编码映射:https://www.cnblogs.com/csguo/p/7401874.html

中文的编码在unicode码表中的CJK(CJK 是中文(Chinese)、日文(Japanese)、韩文(Korean)三国文字的缩写)中说明。关于CJK的说明

ISO-8859-1向下兼容ASCII

特别说明: unicode 和 gbk系列编码之间没有确定的算数关系,如果需要准确的转换,必须通过unicode码表和中文字符编码的码表进行转换。

一般情况下:高级的编程语言中都会提供 unicode 和 gbk系列编码之间转换的API,像C/C++中如果未提供,可以采用第三方库的API进行转换,没必要浪费时间,自己造轮子。

java实现文件编码的转换


public static int convertFileEncoding(String srcFilePath,String srcCharset ,
		String destFilePath,String destCharset,boolean isDeleteSrc) throws  IOException {
   
	if(srcFilePath == null || srcFilePath.length() == 0)
		throw new IllegalArgumentException("srcFilePath is empty.");
	if(destFilePath == null || destFilePath.length() == 0)
		throw new IllegalArgumentException("destFilePath is empty.");
	if(srcFilePath.equalsIgnoreCase(destFilePath))
		throw new IllegalArgumentException("srcFilePath is the same as destFilePath");
	
	if(srcCharset == null || srcCharset.length() == 0)
		throw new IllegalArgumentException("srcCharset is empty.");
	if(destCharset == null || destCharset.length() == 0)
		throw new IllegalArgumentException("destCharset is empty.");
	
	if(srcCharset.equalsIgnoreCase(destCharset)) // 编码相同,无需转换
		return 0;
	
	File srcFile = new File(srcFilePath);
	
	FileInputStream fis = null;
	InputStreamReader isr = null;
	BufferedReader br = null;
	
	FileOutputStream fos = null;
	OutputStreamWriter osw = null;

	try {
   
		fis = new FileInputStream(srcFile);
		isr = new InputStreamReader(fis, srcCharset);
		
		// BufferedReader中defaultCharBufferSize = 8192.
		// 即:8192 × 2 byte = 16k
		// 若是utf-8,中文占3个字节,16K / 3  = 5461,即只要每行中文字符数 < 5461,读取的行数就是准确的,
		// 否则,可能会截断一行,多写入'\n',但这种情况一般不存在。
		// 如果源文件中最后一行没有换行符,转码后的文件最后会多写入一个换行符
		br = new BufferedReader(isr);

		// 以UTF-8格式写入文件,file.getAbsolutePath()即该文件的绝对路径,false代表不追加直接覆盖,true代表追加文件
		fos = new FileOutputStream(destFilePath, false);
		osw = new OutputStreamWriter(fos, destCharset);

		String str = null;

		// 创建StringBuffer字符串缓存区
		StringBuffer sb = new StringBuffer();
		int lines = 0;

		// 通过readLine()方法遍历读取文件
		while ((str = br.readLine()) != null) {
   
			
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值