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 Content Length 不同。
MessageBox.Show(sr.BaseStream.Length.ToString());
MessageBox.Show(sr.ReadToEnd().Length.ToString());
为什么是StreamReader和sr。BaseStream.Seek(( 即使在 UTF8 编码中也能提供垃圾字符
正是因为UTF-8,sr.BaseStream
才给出了垃圾字符。 :)
StreamReader
是一个相对"更智能"的流。它了解字符串的工作原理,而FileStream
(即sr.BaseStream
( 没有。FileStream
只知道字节。
由于您的文件以 UTF-8(一种可变长度编码(编码,因此像A
、B
和C
这样的字母使用 1 个字节进行编码,但•
字符需要 3 个字节。您可以通过执行以下操作来获取字符需要多少字节:
Console.WriteLine(Encoding.UTF8.GetByteCount("•"));
因此,当您将流移动到"紧随•
之后的位置"时,您实际上并没有经过•
,您只是在它的第二个字节上。
Length
s不同的原因是相似的:StreamReader
给你字符数,而sr.BaseStream
给你字节数。