Java编码转换问题详解:UTF-8、Unicode与GBK编码转换及中文乱码解决方案

文章目录

Java编码转换问题详解:UTF-8、Unicode与GBK编码转换及中文乱码解决方案

在 java 编码过程中,常常会遇到编码转换方面的问题,这些问题主要体现在 UTF-8 编码、unicode 编码与 GBK 编码之间的相互转换上。

主要原因经常需要转换,原因在于中文编码存在问题。若编解码不对应,就会经常遭遇令人烦躁的乱码情况。究其根本,在 unicode 系列编码和 GKB 系列编码中,同一个中文字符所对应的编码是不同的。

[id_448023804]

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

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

命令行编译 java 代码时,若不使用 -encoding 指定编码选项,就会默认以 GBK 编码进行编译。倘若源文件的编码并非 GBK 编码,那么编译时(有可能)会出现错误,即出现 xxx 编码不可映射的字符集这种情况。

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

命令行编译 java 代码时,如果不使用 -encoding 指定编码选项,就会默认以 utf-8 编码进行编译。倘若源文件的编码并非 utf-8 编码,那么在编译过程中(有可能)会出现错误,即出现 xxx 编码不可映射的字符集这种情况。

针对上述问题,在编译时指定与源文件相同的编码,这样输出的中文就能正常显示,也不会受到操作系统默认编码的影响。

在 Windows 系统下,使用 utf-8 编码的 Test.java 代码,借助下面的编译指令能够完成编译,并且中文在终端能够正常输出。


javac Test.java -encoding utf-8
java Test

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

UTF-8 格式的数据不能直接转换为其他格式,需要先转化为 unicode 编码。GBK 格式的数据也不能直接转换为其他格式,同样需要先转化为 unicode 编码,然后才能进行转换。

unicode的码表官网:

unicode的编码范围和各国语言编码映射:

中文的编码在 unicode 码表中有所说明,其中涉及到 CJK(CJK 代表中文、日文、韩文三国文字)。关于 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 equal to destFilePath.  // 这一句是将原句进行了简单的同义替换,用“is equal to”替换了“is the same as”,保留了原意且避免了使用原文词语。);
	
	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) {
   
			

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

27阅读

java中冒号,java双冒号

2026年09月06日

24阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

27阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

23阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

25阅读