StreamReader的Read方法无法读取指定的字符数(StreamReader Read me

2019-06-25 23:24发布

我要解析一个大的文件,所以不要做的:

 string unparsedFile = myStreamReader.ReadToEnd(); // takes 4 seconds
 parse(unparsedFile); // takes another 4 seconds

我要带的前4秒的优势,并尝试做一些喜欢做在同一时间两件事:

        while (true)
        {
            char[] buffer = new char[1024];

            var charsRead = sr.Read(buffer, 0, buffer.Length);

            if (charsRead < 1)
                break;

            if (charsRead != 1024)
            {
                Console.Write("Here");  // debuger stops here several times why?
            }

            addChunkToQueue(buffer); 
        }

这里是debuger的图像:(我加int counter上显示我们读什么迭代小于1024个字节)

请注意,那里有643个字符阅读,而不是1024在接下来的迭代,我得到:

我想我应该读1024个字节的所有时间,直到我最后一次迭代,其中remeining字节小于1024。

所以我的问题是 ,为什么会读字符的“随机”数我扔迭代while循环?


编辑

我不知道什么样的流我处理。 我喜欢执行的过程:

        ProcessStartInfo psi = new ProcessStartInfo("someExe.exe")
        {
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            UseShellExecute = false,
            CreateNoWindow = true,
        };

        // execute command and return ouput of command
        using (var proc = new Process())
        {
            proc.StartInfo = psi;
            proc.Start();                               

            var output = proc.StandardOutput;  //  <------------- this is where I get the strem

            //if (string.IsNullOrEmpty(output))
            //output = proc.StandardError.ReadToEnd();

            return output;
        }
    }

Answer 1:

从文档: http://msdn.microsoft.com/en-us/library/9kstw824

当使用Read方法,它是更有效地使用的缓冲区的大小与流,其中该内部缓冲器被设置到所需的块大小,并总是读小于块大小的内部缓冲器相同 。 如果流构建当内部缓冲器的大小是未指定的,其默认大小为4千字节(4096个字节)。 如果你操作的数据读入缓冲区后的基本流的位置,底层流的位置可能不符合内部缓冲器的位置。 到复位内部缓冲器,调用DiscardBufferedData方法; 但是,这种方法会降低性能,应该只在所谓的绝对必要的。

所以对于返回值,该文档说:

字符的已读取的0,如果在流的>端部数量,或者没有数据被读出。 的数量将小于或等于计数参数,这取决于是否是流中可用的数据。

或者,总结 - 你的缓冲区和底层缓冲区的大小也不一样,因此你会得到你的缓冲区的部分填充,作为底层一个没有被填满呢。



Answer 2:

一方面,你正在阅读的字符 ,而不是字节 。 有一个巨大的差异。

至于为什么它不一定一下子读到的一切:也许没有,现有的数据量,以及StreamReader决定给你什么它得到,而不是阻止了不确定的时间量来填补你的缓冲区。 这是完全有权利这样做。

这是即将从本地文件,或通过网络? 通常,本地文件的操作更容易,以填补比网络下载的缓冲区,但你根本不应该依赖缓冲区无论哪种方式填充。 如果这是一个“文件”(即读取使用FileStream ),却偏偏要坐在一个网络共享...好,这是我在知识的灰色地带:)这是一个流-对待它的方式。



Answer 3:

这取决于你正在阅读的实际流。 如果是这样的文件流我想这是相当不可能获得“部分”数据。 但是,如果你从网络流中读取,你不得不预期的数据有不同长度的块。



文章来源: StreamReader Read method doesn't read number of chars specified