文章目录
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的说明。
特别说明: 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) {