1.Java字符串相关
1.1 Java字符串编码方式
Java字符串由char值序列组成。char数据类型是一个采用UTF-16编码表示Unicode码点的编码单元。大多数常用的Unicode字符使用一个编码单元可以表示,而辅助字符需要两个编码单元表示。
强烈建议不要在程序中使用char类型,除非确实需要处理UTF-16编码单元。最好将字符串作为抽象数据类型处理。
1.2 JNI接口
C字符串是以null结尾的字节序列。
JNI由两组操作字符串的函数,一组把Java字符串转换成“改良的UTF-8”字节序列,另一组将它们转换成UTF-16数值数组,也就是jchar数组。
Java字符串与"改良的UTF-8"字节序列相互转换:
jstring (JNICALL *NewStringUTF) (JNIEnv *env, const char *utf);
根据以全0字节结尾的“改良的UTF-8”字节序列,返回一个新的Java字符串对象
jsize (JNICALL *GetStringUTFLength) (JNIEnv *env, jstring str);
返回以UTF-8编码所需的字节个数
const char* (JNICALL *GetStringUTFChars) (JNIEnv *env, jstring str, jboolean *isCopy);
返回指向字符串的“改良UTF-8”编码的指针。直到ReleaseStringUTFChars函数调用前,该指针一直有效。
如果虚拟机使用UTF-16或UTF-32字符作为其内部字符串的表示,该函数会分配一个新的内存块来存储等价的“改良UTF-8”编码字符。
void (JNICALL *ReleaseStringUTFChars) (JNIEnv env, jstring str, const char chars);
通知JVM本地代码不再需要通过GetStringUTFChars返回的指针访问Java字符串。
Java字符串与UTF-16数值数组相互转换(如果C代码使用了Unicode,使用该组转换函数):
jstring (JNICALL *NewString) (JNIEnv *env, const jchar *unicode, jsize len);
根据Unicode字符串返回一个新的Java字符串对象
jsize (JNICALL *GetStringLength) (JNIEnv *env, jstring str);
返回字符串中字符的个数
const jchar *(JNICALL *GetStringChars) (JNIEnv *env, jstring str, jboolean *isCopy);
返回指向字符串的Unicode编码的指针,直到ReleaseStringChars函数调用之前,该指针一直有效。
void (JNICALL *ReleaseStringChars) (JNIEnv *env, jstring str, const jchar *chars);
通知JVM本地代码不再需要通过GetStringChars返回的指针访问Java字符串。
1.3 DataOutput接口方法writeUTF使用改良的UTF-8
writeUTF方法使用“改良的UTF-8”写出字符串。
改良的UTF-8:
首先用UTF-16表示
其结果之后使用UTF-8规则进行编码
修订后的编码方式对于编码大于0xFFFF的字符的处理有所不同,这是为了向后兼容在Unicode还没有超过16位时构建的虚拟机。
2.文本IO
Java针对文本字符使用的是Unicode标准,最常见的编码方式是UTF-8
在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,就转换为UTF-8编码。
用记事本编辑的时候,从文件读取的UTF-8字符被转换为Unicode字符到内存里,编辑完成后,保存的时候再把Unicode转换为UTF-8保存到文件:
浏览网页的时候,服务器会把动态生成的Unicode内容转换为UTF-8再传输到浏览器: