use*_*258 2 java string encoding utf-8
在Java中,我一直在尝试使用UTF-8编码将String写入文件,稍后将由另一个用不同编程语言编写的程序读取.在这样做时,我注意到将String编码为字节数组时创建的字节似乎没有正确的字节值.
我将问题缩小到符号"£",这似乎在编码为UTF-8时产生不正确的字节
byte[] byteArray = "£".getBytes(Charset.forName("UTF-8"));
// Print out the Byte Array of the UTF-8 converted string
// Upcast byte values to print the bytes as unsigned
for (byte signedByte : byteArray) {
System.out.print((signedByte & 0xFF) + " ");
}
Run Code Online (Sandbox Code Playgroud)
这输出6个字节的十进制值:239 190 130 239 189 163,以十六进制表示:ef be 82 ef bd a3
http://www.utf8-chartable.de/但是说十六进制中"£"的值是:c2 a3,输出应该是:194 163
当编码为UTF-8时,其他字符串似乎产生正确的字节,所以我想知道为什么Java为"£"生成这6个字节,以及我应该如何通过使用UTF-8编码将字符串正确地转换为字节数组
我也试过了
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8");
out.write("£");
out.close();
Run Code Online (Sandbox Code Playgroud)
但这产生了相同的6个字节
我怀疑问题是你在Java代码中使用字符串文字,使用编辑器将其写入一个编码 - 但是你在编译时没有指定相同的编码.换句话说,我怀疑你的"£"字符串实际上根本不是单个符号.
这应该很容易验证.例如:
char[] chars = "£".toCharArray();
for (char c : chars) {
System.out.println((int) c);
}
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,您可以使用Unicode转义序列使用纯ASCII表示来指定字符串:
String pound = "\u00a3";
// Now encode as before
Run Code Online (Sandbox Code Playgroud)
我相信你会得到正确的字节.例如:
import java.nio.charset.Charset;
class Test {
public static void main(String[] args) throws Exception {
String pound = "\u00a3";
byte[] bytes = pound.getBytes(Charset.forName("UTF-8"));
for (byte b : bytes) {
System.out.println(b & 0xff); // 194, 163
}
}
}
Run Code Online (Sandbox Code Playgroud)