gpt4 book ai didi

c# - 使用 EndOfStream 属性后的 StreamReader.BaseStream 问题

转载 作者:太空宇宙 更新时间:2023-11-03 15:25:08 27 4
gpt4 key购买 nike

首先我明白我可以用不同的方式解决这个问题。我想这个问题的存在只是因为以不正确的方式使用了不同的方法。但我想知道在我的示例中到底发生了什么。

我正在使用 StreamReader 读取文件。为了从中获取字节,我决定使用 BaseStream.Read:

        int length = (int)reader.BaseStream.Length;
byte[] file = new byte[length];
while(!reader.EndOfStream)
{
int readBytes = reader.BaseStream.Read(file, 0,
(length-offset)>bufferSize?bufferSize:(length - offset));
for (int i = 0; i<readBytes; i++)
{
...
}
offset += readBytes;
}

在读取之前使用属性 StreamReader.EndOfStream 时,BaseStream.Read 拒绝获取最后 1024 个字节。后来查到资料,说EndOfStream试图读取1个字节,但实际上由于性能原因他读取了1024个字节。显然这 1kb 变得不可能达到。

编辑:如果我删除代码中的reader.EndOfStream 属性,reader.BaseStream.Read 将正常工作。这是问题的重点。

同样,我明白,这个代码示例绝对是低效的。我只是想了解流在那个例子中是如何工作的,这个问题是否仅仅因为错误的代码而存在(或者 StreamReader.BaseStream 有一些问题)?提前致谢。

最佳答案

不是 StreamReader.BaseStream 有一些问题,而是您的代码中的问题。当您直接使用包装在 StreamReader 中的 Stream 时。

来自 MSDN 关于 StreamReader.DiscardBufferedData :

You need to call this method only when the position of the internal buffer and the BaseStream do not match. These positions can become mismatched when you read data into the buffer and then seek a new position in the underlying stream.

这意味着,在你的情况下,当 Stream 已经到达结束位置时, StreamReader internal buffer 的位置仍然保持之前的值您直接读取底层流,因此 reader.EndOfStream 仍然 = false。这就是为什么您无法完成循环的原因。

编辑:

我觉得你漏掉了什么,我给你这段代码来证明文件成功到达结尾。运行它,您会看到您的应用重复说:我在文件末尾!

static void Main()
{
using (StreamReader reader = new StreamReader(@"yourFile"))
{
int offset = 0;
int bufferSize = 102400;
int length = (int)reader.BaseStream.Length;
byte[] file = new byte[length];
while (!reader.EndOfStream)
{


// Add this line:
Console.WriteLine(reader.BaseStream.Position);
Console.ReadLine();



int readBytes = reader.BaseStream.Read(file, 0,
(length - offset) > bufferSize ? bufferSize : (length - offset));
string str = Encoding.UTF8.GetString(file, 0, readBytes);
offset += readBytes;
if (reader.BaseStream.Position == length)
{
Console.WriteLine("I'm at the end of the file! Current Tickcount: " + Environment.TickCount);
Thread.Sleep(100);
}
}
}
}

编辑2

But still , offset and length should be equal, im my case length - offset = 1024 (in case of files that bigger than 1kb). Maybe I'm doing something wrong, but if I use files with size less than 1kb, readBytes always equals 0.

因为您第一次调用 while (!reader.EndOfStream),读取器必须读取文件(本例为 1024 字节 - 读取字节到内部缓冲区)以确定文件是否结束或不是(见我在上面添加的两行代码),在它读取文件后寻找 1024 字节,这就是为什么 length - offset = 1024,如果你的文件很小超过 1kb 然后在第一次调用时,它已经找到文件末尾。这是您丢失数据的地方。

第二次调用它,它不寻找,因为你没有向读者发送任何读取请求,所以它认为不变,那么它不需要再次读取文件来检查是否在文件末尾,这就是为什么第二次通话不会丢失数据。

关于c# - 使用 EndOfStream 属性后的 StreamReader.BaseStream 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35668357/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com