在 java 中使用 UTF-8 字符集输出流将 UTF-16 字符写入文件,但文件中的结果数据仍为 UTF-16。为什么?
Written UTF-16 character to a file by using UTF-8 charset output stream in java but resulting data on file is still UTF-16. why?
创建了一个简单的 java 程序来查看 utf 8 字符集是否可以保存 utf16 字符,它确实能够保存它。为什么?
如果 UTF-08 可以保存 UTF-16 字符,那么使用 UTF-16 和 UTF-8 有什么区别。
两个测试字符的 unicode 值都超出了 UTF-8 范围,即 256。
✈ unicode 值:9992
❄ unicode 值:10052
请看示例程序:-
import java.io.*;
import java.nio.charset.Charset;
public class UTFSizeTest {
public static void main(String[] args) throws IOException {
System.out.println("Default Charset=" + Charset.defaultCharset());
write("UTF-16");
write("UTF-8");
write(null);
}
private static void write(String utf) throws IOException {
final String fileName = "someFile" + utf;
Writer writer;
if (utf == null) {
writer = new OutputStreamWriter(new FileOutputStream(fileName));
} else {
writer = new OutputStreamWriter(new FileOutputStream(fileName), utf);
}
for (int i = 0; i < 2; i++) {
writer.write("✈ ❄");
writer.write("\n");
}
writer.close();
System.out.println(fileName + " size: "+ new File(fileName).length());
}
}
使用 utf-16 和 utf-8 在两个文件上写入相同的数据:-
✈ ❄
✈ ❄
从控制台输出中可以看出,UTF-16 和 UTF-8 的文件大小也几乎相同。
控制台输出如下:-
默认字符集=UTF-8
someFileUTF-16 大小:18
someFileUTF-8 大小:16
someFilenull 大小:16
如果 utf-08 可以保存 16 位 unicode 就好了,为什么要在 java.
中使用 uff-16
谢谢。
我问这个问题是因为我的无知。
我虽然 UTF-8 最多只能保存字符点 8 位,而 Unicode 需要 UTF-16 或 Unicode 字符表示由 2 个字节或 16 位表示的字符。
但是看了一些论坛后我发现UTF-8、UTF-16和UTF-32都是Unicode字符的不同编码方式,实际上UTF-8最多可以表示6个字符bytes/48位。
谢谢
Created a simple java program to see if utf 8 charset can save utf16 character
可以。 UTF-8 和 UTF-16 只是同一个 Unicode 字符集的不同编码。两种编码都旨在支持所有 Unicode 代码点,包括现在和可预见的未来。
and it does able to save it. Why?
因为它们都支持相同的 Unicode 代码点。按照设计,在各种 UTF 之间进行转换是一种无损操作。
If UTF-08 can save UTF-16 characters than whats the difference in using UTF-16 and UTF-8.
UTF-8 优于 UTF-16 的主要原因是:
UTF-8 向后兼容 7 位 ASCII,因此很多遗留代码可以在不中断的情况下迁移到 UTF-8。
对于大多数语言,尤其是基于拉丁语的语言,UTF-8 比 UTF-16 更紧凑,因此可以节省内存、磁盘 space 和带宽。但是,在某些情况下,主要是亚洲语言,但也有符号(如您的示例),其中 UTF-16 实际上比 UTF-8 更紧凑。
please see the sample program:-
...
Data written same on both files using utf-16 and utf-8 :-
是的,它们代表相同的 Unicode 代码点,因此它们呈现相同的 Unicode 文本 viewer/editor.但是它们的物理字节有很大的不同:
✈
UTF-8: e2 9c 88
UTF-16LE: 08 27
UTF-16BE: 27 08
❄
UTF-8: e2 9d 84
UTF-16LE: 44 27
UTF-16BE: 27 44
Size of the files is also almost the same for UTF-16 and UTF-8 as can seen on console output.
在上面的示例中,您选择了 2 个不需要 UTF-16 代理项对对其进行编码的 Unicode 代码点,因此它们在 UTF-16 中使用 2 个字节而不是 4 个字节。在 UTF-8 中,每个占用 3 个字节,但大小差异通过它们之间的 1 字节 U+0020 SPACE
字符减少。尝试使用更多的低代码点值和高代码点值组合来编写更长的字符串,您应该会看到文件大小的变化范围更大。
If utf-08 can save 16 bits unicode just fine fine than why to use uff-16 in java.
尽管 UTF-8 和 UTF-16 都是可变长度编码,但 UTF-16 的可变长度往往小于 UTF-8。 UTF-8 的 1、2 和 3 字节格式中的所有代码点都适合 UTF-16 的 2 字节格式,使 UTF-16 比 UTF-8 更接近固定长度。这也意味着 UTF-16 更容易在内部向前和(特别是)向后寻找,每个代码点只需跳转 2 或 4 个字节,而使用 UTF-8 则每个代码点必须跳转 1、2、3 或 4 个字节代码点,因此 UTF-8 的解码逻辑比 UTF-16 更复杂。
请记住,当 Java、Windows 等采用 Unicode 时,那是在 UTF-16 存在之前,当时所有可用的代码点很容易适合 UCS-2,即固定长度的编码。直到后来,Unicode 才超越了 UCS-2,才发明了 UTF-16 来取而代之。到那时,重新编写已迁移到 Unicode 的代码为时已晚,因此 UTF-16 必须保持与 UCS-2 的向后兼容性。此外,现实世界中使用的许多 Unicode 数据仍然倾向于适合 UCS-2,只有更高的代码点才真正需要额外的字节来编码 UTF-16 代理项。
因此,这通常使 UTF-16 成为处理数据的更合适选择。与 UTF-8 相比,它是内存使用和处理开销之间更好的折衷,至少在处理非 ASCII 字符时是这样。但 UTF-8 向后兼容 ASCII,它往往是一种更适合存储和交换数据的格式。
创建了一个简单的 java 程序来查看 utf 8 字符集是否可以保存 utf16 字符,它确实能够保存它。为什么? 如果 UTF-08 可以保存 UTF-16 字符,那么使用 UTF-16 和 UTF-8 有什么区别。
两个测试字符的 unicode 值都超出了 UTF-8 范围,即 256。
✈ unicode 值:9992
❄ unicode 值:10052
请看示例程序:-
import java.io.*;
import java.nio.charset.Charset;
public class UTFSizeTest {
public static void main(String[] args) throws IOException {
System.out.println("Default Charset=" + Charset.defaultCharset());
write("UTF-16");
write("UTF-8");
write(null);
}
private static void write(String utf) throws IOException {
final String fileName = "someFile" + utf;
Writer writer;
if (utf == null) {
writer = new OutputStreamWriter(new FileOutputStream(fileName));
} else {
writer = new OutputStreamWriter(new FileOutputStream(fileName), utf);
}
for (int i = 0; i < 2; i++) {
writer.write("✈ ❄");
writer.write("\n");
}
writer.close();
System.out.println(fileName + " size: "+ new File(fileName).length());
}
}
使用 utf-16 和 utf-8 在两个文件上写入相同的数据:-
✈ ❄
✈ ❄
从控制台输出中可以看出,UTF-16 和 UTF-8 的文件大小也几乎相同。
控制台输出如下:-
默认字符集=UTF-8
someFileUTF-16 大小:18
someFileUTF-8 大小:16
someFilenull 大小:16
如果 utf-08 可以保存 16 位 unicode 就好了,为什么要在 java.
中使用 uff-16谢谢。
我问这个问题是因为我的无知。 我虽然 UTF-8 最多只能保存字符点 8 位,而 Unicode 需要 UTF-16 或 Unicode 字符表示由 2 个字节或 16 位表示的字符。
但是看了一些论坛后我发现UTF-8、UTF-16和UTF-32都是Unicode字符的不同编码方式,实际上UTF-8最多可以表示6个字符bytes/48位。
谢谢
Created a simple java program to see if utf 8 charset can save utf16 character
可以。 UTF-8 和 UTF-16 只是同一个 Unicode 字符集的不同编码。两种编码都旨在支持所有 Unicode 代码点,包括现在和可预见的未来。
and it does able to save it. Why?
因为它们都支持相同的 Unicode 代码点。按照设计,在各种 UTF 之间进行转换是一种无损操作。
If UTF-08 can save UTF-16 characters than whats the difference in using UTF-16 and UTF-8.
UTF-8 优于 UTF-16 的主要原因是:
UTF-8 向后兼容 7 位 ASCII,因此很多遗留代码可以在不中断的情况下迁移到 UTF-8。
对于大多数语言,尤其是基于拉丁语的语言,UTF-8 比 UTF-16 更紧凑,因此可以节省内存、磁盘 space 和带宽。但是,在某些情况下,主要是亚洲语言,但也有符号(如您的示例),其中 UTF-16 实际上比 UTF-8 更紧凑。
please see the sample program:-
...
Data written same on both files using utf-16 and utf-8 :-
是的,它们代表相同的 Unicode 代码点,因此它们呈现相同的 Unicode 文本 viewer/editor.但是它们的物理字节有很大的不同:
✈
UTF-8: e2 9c 88
UTF-16LE: 08 27
UTF-16BE: 27 08
❄
UTF-8: e2 9d 84
UTF-16LE: 44 27
UTF-16BE: 27 44
Size of the files is also almost the same for UTF-16 and UTF-8 as can seen on console output.
在上面的示例中,您选择了 2 个不需要 UTF-16 代理项对对其进行编码的 Unicode 代码点,因此它们在 UTF-16 中使用 2 个字节而不是 4 个字节。在 UTF-8 中,每个占用 3 个字节,但大小差异通过它们之间的 1 字节 U+0020 SPACE
字符减少。尝试使用更多的低代码点值和高代码点值组合来编写更长的字符串,您应该会看到文件大小的变化范围更大。
If utf-08 can save 16 bits unicode just fine fine than why to use uff-16 in java.
尽管 UTF-8 和 UTF-16 都是可变长度编码,但 UTF-16 的可变长度往往小于 UTF-8。 UTF-8 的 1、2 和 3 字节格式中的所有代码点都适合 UTF-16 的 2 字节格式,使 UTF-16 比 UTF-8 更接近固定长度。这也意味着 UTF-16 更容易在内部向前和(特别是)向后寻找,每个代码点只需跳转 2 或 4 个字节,而使用 UTF-8 则每个代码点必须跳转 1、2、3 或 4 个字节代码点,因此 UTF-8 的解码逻辑比 UTF-16 更复杂。
请记住,当 Java、Windows 等采用 Unicode 时,那是在 UTF-16 存在之前,当时所有可用的代码点很容易适合 UCS-2,即固定长度的编码。直到后来,Unicode 才超越了 UCS-2,才发明了 UTF-16 来取而代之。到那时,重新编写已迁移到 Unicode 的代码为时已晚,因此 UTF-16 必须保持与 UCS-2 的向后兼容性。此外,现实世界中使用的许多 Unicode 数据仍然倾向于适合 UCS-2,只有更高的代码点才真正需要额外的字节来编码 UTF-16 代理项。
因此,这通常使 UTF-16 成为处理数据的更合适选择。与 UTF-8 相比,它是内存使用和处理开销之间更好的折衷,至少在处理非 ASCII 字符时是这样。但 UTF-8 向后兼容 ASCII,它往往是一种更适合存储和交换数据的格式。