你好,我注意到当我使用UTF-8编码(没有BOM)保存文本文件时,我能够在C#上使用UTF-16编码完美地读取它。现在这让我有点困惑,因为UTF-8只使用了8位,对吧?而utf-16对每个字符都需要16位。
现在想象一下,我把这个文件中的字符串“ab”写成UTF-8,然后那里有一个字母“a”&另一个用于“b”。
好的,但是在使用UTF-16字符集时如何读取此UTF-8文件?我看到它的方式,在读取文件时,“ab”的两个字节将被误认为只包含两个字节的一个字符。因为UTF-16需要那2个字节。
这就是我读它的方式(t.txt被编码为UTF-8):
using(StreamReader sr = new StreamReader(File.OpenRead("t.txt"), Encoding.GetEncoding("utf-16")))
{
Console.Write(sr.ReadToEnd());
Console.ReadKey();
}
答案 0 :(得分:5)
查看http://www.joelonsoftware.com/articles/Unicode.html,它将回答您的所有unicode问题
答案 1 :(得分:1)
The '8' means it uses 8-bit blocks to represent a character.
这并不意味着每个字符都需要固定的8位。每个字符的块数从1到4不等(尽管字符长度可以达到6个字节)。
尝试这个简单的测试,
File.ReadAllBytes()
阅读文本文件(正如您在代码中所做的那样)。 byte[] utf8 = File.ReadAllBytes(@"E:\SavedUTF8.txt");
byte[] ansi = File.ReadAllBytes(@"E:\SavedANSI.txt");
注意,File.ReadAllBytes()尝试根据字节顺序标记的存在自动检测文件的编码。可以检测到编码格式UTF-8和UTF-32(big-endian和little-endian)。
有趣的结果
SavedUTF8.txt
包含字符
a
:字节数组中的字节数= 1 ©
(UTF + 00A9)(Alt + 0169):字节数组中的字节数= 2 €
:( UTF + E0A080)(Alt + 14721152)字节数组中的字节数= 3 ANSI
编码总是需要8位(即在上面的示例中,无论文件中的字符如何,字节数组总是大小为1)。正如@tchrist所指出的,UTF16每个字符占用2或4个字节(而不是每个字符固定的2个字节)。
编码表(来自here)
以下字节序列用于表示字符。要使用的序列取决于字符的Unicode编号:
U-00000000 – U-0000007F: 0xxxxxxx
U-00000080 – U-000007FF: 110xxxxx 10xxxxxx
U-00000800 – U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 – U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 – U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 – U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
xxx 位位置用二进制表示中的字符代码编号的位填充。最右边的 x 位是最低有效位。只能使用可以表示字符代码号的最短可能的多字节序列。请注意,在多字节序列中,第一个字节中前导1位的数量与整个序列中的字节数相同。
确定角色的大小
表示非ASCII字符的多字节序列的第一个字节始终在0xC0到0xFD的范围内,它表示该字符的后续字节数。
这意味着2字节字符(110
)的前导位与3字节字符(1110
)的前导位不同。这些前导位可用于唯一标识字符所占的字节数。
更多信息
答案 2 :(得分:1)