如何使用 FileStream 和 StreamReader 找到读取 UTF-8 文件中起始字符的条件?

How to find condition that start char in UTF-8 file is read, using FileStream and StreamReader?

在 C# .NET 4.0(实际上是 4.5.2)中,我的代码读取一个 UTF-8 文件。

            FileStream fstream = new FileStream(path, FileMode.Open);
            BufferedStream stream = new BufferedStream(fstream);

            using (StreamReader reader = new StreamReader(stream, new UTF8Encoding())) {              
                int i;
                while((i = reader.Read()) > -1) {
                    //a guess at a condition that is true I.F.F. reader has read character 1 of the file
                    if (stream.Position == (0 + sizeof(char)) || stream.Position == (0 + sizeof(int)) ) {
                        //while loop has reader read through all characters, 
                        //but within this block, the reader has surely read character 1?
                        char c = (char)i;


                    }
                }

                reader.Close();
                return 0;
            }

I.F.F。我们达到 StreamReader 读取 UTF-8 文件的起始字符的条件,然后 运行 在读取的第一个字符上执行某些函数。

使用FileStream和StreamReader读取UTF-8文件,如何知道是否满足上述条件?

我正在寻找答案,请使用 C# .NET 4.0 System.IO 命名空间中已存在的 属性 或方法。我认为使用 Stream.Position (BufferedStream.Position) 属性 是找出 reader 在文件中的位置(即在什么字符处)的明显方法,但是在尝试以 '0''9'(48 到 57)中的某个字符开头的 UTF-8 文件,带有 reader.Read() 的循环读取该字符,然后 stream.Position = 43 。我不知道为什么所有整数值中的43是读取第1个字符后stream.Position的值,或者43是什么意思。

update:随着循环迭代,reader读取更多的字符,stream.Position的值仍然是43。我不知道位置属性 就有用了。

bool first = true;    

while((i = reader.Read()) > -1) 
{
    if (first)
    {
        first = false;
        // Do first character things
    }

请注意第一个字符的概念很复杂:如果第一个字形是 è,它在文件中占据两个字节会怎样?流位置至少为 2 :-)

一般来说,你可以检查StreamReader.BaseStreamPosition是什么,但是Position几乎没用,因为可能有多级缓存,或者仅仅是因为对于读取单个 charStreamReader 可能消耗 1-4 个字节(à 是一个字节,而一些 Unicode 字符长 4 个字节)...然后 UTF8 文件可以有一个 BOM(一个初始头长 3 个字节)。这也是通常从 StreamReader.

中跳过的

不过,如果需要,您可以子class 整个 StreamReader class,覆盖所有 Read*,并保留一个内部标志 SomethingHasBeenRead.不难(都是virtual in StreamReader)...只是有点长。