Android 播放mp3 tag乱码分析之java 篇

在Java程序中的字符,不管是中文的还是英文的,都是占用二个字节,这个结论我们大家都烂熟于心了,但是纠结是为什么呢?

其实是因为 char 类型 就好比双字节无符号整数




UTF-16编码 与Unicode编码是一样的,只不过UTF-16在编码时会在码流前加上"FE FF"两个字节的内容,表示字符是以UTF-16格式存储的,在读取时程序就会知道是UTF-16编码的字符。

中文字符转UTF-16
byte[] encodeArr = String.valueOf(chineseChar).getBytes("UTF-16");


题外话:

以UTF-16写入文件时,也会把文件编码标志FE FF 写入文件开头,但写入时不能编一码写一次文件, 因为这样每次以UTF-16编码时,都会生成编码标志,且写文件时也写入了,这样只需第一次写文件时需要的标志却存入了多次,所以当以UTF-16存储字符时,最好一次性编码完成后再写入,或当字符太多时,我们用OutputStreamWriter进行包装后可以方便地进行多次写入,而不会多次写入文件编码标志,或者我们就用字节流来存,自已负责编码,但从第二次编码后写文件开始,手动去掉文件编码标志后再存入也是可以的,只不过没有像直接以字符流多次写入那样方便了。


我们研究的MP3 tag,不存在写入问题。但是想要正确读取tag信息,还是了解一下的好!

//以字节流读取有编码标志的UTF-8文件
FileInputStream fi = new FileInputStream("...");
byte[] b = new byte[1024];
int readCount = fi.read(b);
//手动丢弃前三个字节的内容
System.out.println(new String(b, 3, readCount - 3, "UTF-8"));

字符UTF-8字符与Unicode编码兼容,中文字符以UTF-8编码时,占三个字节。
英文使用的UTF-8编码规则模板是0xxxxxxx

中文的模版 是 :1110xxxx 10xxxxxx 10xxxxxx
如"中"字的Unicode编码是4E2D。4E2D在0800-FFFF之间,所以要用上面的三字节规则模板,将4E2D写成二进制是:0100 1110 0010 1101,将这个比特流按三字节模板的分段方法分为0100 111000 101101,依次代替模板中的x,得到:1110-0100 10-111000 10-101101,即 E4 B8 AD,这就是"中"字的UTF8的编码。

我要强调的是:

用Java程序入文件中以UTF-8编码方式存入字符时,是不会在文件头加上编码标志的。但如果在windows 中利用各种工具利用千千静听,转MP3文件为UTF-8保存时,会在文件开开头写入文件编码标志 EF BB BF 三个字节长度的编码标志,这时如果使用字节流方式读取有编码标示的UTF-8文件时,会有问题,这也就是为什么我们手动转成utf-8了,但是在读取韩文日文中文等...还是会出现乱码问题的原因。此时只能以字节流读出后去掉前三个字节内容。

你可能感兴趣的:(android)