StreamReader Read 方法不读取指定的字符数 [英] StreamReader Read method doesn't read number of chars specified

查看:23
本文介绍了StreamReader Read 方法不读取指定的字符数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须解析一个大文件,而不是这样做:

I have to parse a large file so instead of doing:

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

我想利用前 4 秒的时间,尝试同时做以下事情:

I want to take advantage of the first 4 seconds and try to do both things at the same time by doing something like:

        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); 
        }

这是调试器的图像:(我添加了 int counter 以显示我们读取的小于 1024 字节的迭代)

here is the image of the debuger: (I added int counter to show on what iteration we read less than 1024 bytes)

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

Note that there where 643 chars read and not 1024. On the next iteration I get:

我想我应该一直读取 1024 个字节,直到最后一次迭代,其中剩余字节小于 1024.

I think I should read 1024 bytes all the time until I get to the last iteration where the remeining bytes are less than 1024.

所以我的问题是为什么我会在迭代抛出 while 循环时读取随机"数量的字符?

So my question is why will I read "random" number of chars as I iterate throw the while loop?

我不知道我在处理什么样的流.我执行如下流程:

I don't know what kind of stream I am dealing with. I Execute a process like:

        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;
        }
    }

推荐答案

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

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

When using the Read method, it is more efficient to use a buffer that is the same size as the internal buffer of the stream, where the internal buffer is set to your desired block size, and to always read less than the block size. If the size of the internal buffer was unspecified when the stream was constructed, its default size is 4 kilobytes (4096 bytes). If you manipulate the position of the underlying stream after reading data into the buffer, the position of the underlying stream might not match the position of the internal buffer. To reset the internal buffer, call the DiscardBufferedData method; however, this method slows performance and should be called only when absolutely necessary.

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

So for the return value, the docs says:

已读取的字符数,如果在末尾则为 0> 流,但未读取任何数据.该数字将小于或等于到count参数,取决于数据是否可用在流中.

The number of characters that have been read, or 0 if at the end of > the stream and no data was read. The number will be less than or equal to the count parameter, depending on whether the data is available within the stream.

或者,总而言之 - 您的缓冲区和底层缓冲区的大小不同,因此您的缓冲区被部分填充,因为底层缓冲区尚未被填充.

Or, to summarize - your buffer and the underlying buffer are not the same size, thus you get partial fill of your buffer, as the underlying one is not being filled up yet.

这篇关于StreamReader Read 方法不读取指定的字符数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆