StreamReader Read方法不读取指定的字符数

时间:2012-07-02 18:54:25

标签: c# streamreader

我必须解析一个大文件而不是:

 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字节)

enter image description here

请注意,其中643个字符读取而不是1024.在下一次迭代中,我得到:

enter image description here

我想我应该一直读取1024个字节,直到我到达最后一次迭代,其中重新记录的字节小于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;
        }
    }

3 个答案:

答案 0 :(得分:4)

首先,您正在阅读字符,而不是字节。这有很大的不同。

至于为什么它不一定会同时读取所有内容:也许没有那么多可用的数据,并且StreamReader已经决定给你什么,而不是阻止不确定的时间填补你的缓冲区。完全有权这样做。

这是来自本地文件还是来自网络?通常,本地文件操作比网络下载更有可能填充缓冲区,但无论哪种方式,您都不应该依赖于填充的缓冲区。如果它是一个“文件”(即使用FileStream读取)但它碰巧坐在网络共享上...好吧,据我所知这是一个灰色区域:)它是一个流 - 以这种方式对待它。 / p>

答案 1 :(得分:3)

这取决于您正在阅读的实际流。如果这是文件流,我想它不太可能获得“部分”数据。但是,如果您从网络流中读取数据,则必须预期数据会以不同长度的数据块形式出现。

答案 2 :(得分:2)

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

  

使用Read方法时,使用缓冲区效率更高   与流的内部缓冲区大小相同,其中   内部缓冲区设置为您想要的块大小,并始终读取   小于块大小。如果内部缓冲区的大小是   在构造流时未指定,其默认大小为 4   千字节(4096字节)。如果你操纵的位置   读取数据后的底层流进入缓冲区的位置   底层流可能与内部的位置不匹配   缓冲。要重置内部缓冲区,请调用DiscardBufferedData   方法;但是,这种方法会降低性能并应该调用   只有在绝对必要的时候。

因此,对于返回值,文档说:

  

已读取的字符数,如果在结尾时为0   的&GT;流,没有数据被读取。数量将小于或等于   计数参数,取决于数据是否可用   在溪流内。

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