为什么 StreamReader 和 sr.BaseStream.Seek() 即使在 UTF8 编码中也会给出垃圾字符
Why is StreamReader and sr.BaseStream.Seek() giving Junk Characters even in UTF8 Encoding
abc.txt 文件内容是
ABCDEFGHIJ•XYZ
现在,如果我使用此代码(即定位到位置 9),显示的字符就可以了,
string filePath = "D:\abc.txt";
FileStream fs = new FileStream(filePath, FileMode.Open);
StreamReader sr = new StreamReader(fs, new UTF8Encoding(true), true);
sr.BaseStream.Seek(9, SeekOrigin.Begin);
char[] oneChar = new char[1];
char ch = (char)sr.Read(oneChar, 0, 1);
MessageBox.Show(oneChar[0].ToString());
但是如果 SEEK 位置正好在那个特殊点字符之后,那么我会得到垃圾字符。
所以,如果我搜索到位置 11(即在点位置之后),我会得到垃圾字符
sr.BaseStream.Seek(11, SeekOrigin.Begin);
这应该是'X',因为第11位的字符是X。
我认为文件内容是合法的 UTF8。
还有一件事,
StreamReader BaseStream 长度和 StreamReader Contents Length 不同。
MessageBox.Show(sr.BaseStream.Length.ToString());
MessageBox.Show(sr.ReadToEnd().Length.ToString());
Why is StreamReader and sr.BaseStream.Seek() giving Junk Characters even in UTF8 Encoding
正是因为 UTF-8,sr.BaseStream
给出了垃圾字符。 :)
StreamReader
是比较"smarter"流。它理解 strings 是如何工作的,而 FileStream
(即 sr.BaseStream
)则不然。 FileStream
只知道字节。
由于您的文件是用 UTF-8(一种可变长度编码)编码的,因此像 A
、B
和 C
这样的字母是用 1 个字节编码的,但是 •
字符需要3个字节。您可以通过以下方式获得一个字符需要多少字节:
Console.WriteLine(Encoding.UTF8.GetByteCount("•"));
因此,当您将流移至 "the position just after •
" 时,您实际上并没有移过 •
,您只是在它的第二个字节上。
Length
不同的原因是相似的:StreamReader
给你 个字符 ,而 sr.BaseStream
给你字节数.
abc.txt 文件内容是
ABCDEFGHIJ•XYZ
现在,如果我使用此代码(即定位到位置 9),显示的字符就可以了,
string filePath = "D:\abc.txt";
FileStream fs = new FileStream(filePath, FileMode.Open);
StreamReader sr = new StreamReader(fs, new UTF8Encoding(true), true);
sr.BaseStream.Seek(9, SeekOrigin.Begin);
char[] oneChar = new char[1];
char ch = (char)sr.Read(oneChar, 0, 1);
MessageBox.Show(oneChar[0].ToString());
但是如果 SEEK 位置正好在那个特殊点字符之后,那么我会得到垃圾字符。
所以,如果我搜索到位置 11(即在点位置之后),我会得到垃圾字符
sr.BaseStream.Seek(11, SeekOrigin.Begin);
这应该是'X',因为第11位的字符是X。
我认为文件内容是合法的 UTF8。
还有一件事, StreamReader BaseStream 长度和 StreamReader Contents Length 不同。
MessageBox.Show(sr.BaseStream.Length.ToString());
MessageBox.Show(sr.ReadToEnd().Length.ToString());
Why is StreamReader and sr.BaseStream.Seek() giving Junk Characters even in UTF8 Encoding
正是因为 UTF-8,sr.BaseStream
给出了垃圾字符。 :)
StreamReader
是比较"smarter"流。它理解 strings 是如何工作的,而 FileStream
(即 sr.BaseStream
)则不然。 FileStream
只知道字节。
由于您的文件是用 UTF-8(一种可变长度编码)编码的,因此像 A
、B
和 C
这样的字母是用 1 个字节编码的,但是 •
字符需要3个字节。您可以通过以下方式获得一个字符需要多少字节:
Console.WriteLine(Encoding.UTF8.GetByteCount("•"));
因此,当您将流移至 "the position just after •
" 时,您实际上并没有移过 •
,您只是在它的第二个字节上。
Length
不同的原因是相似的:StreamReader
给你 个字符 ,而 sr.BaseStream
给你字节数.