我必须解析一个大文件而不是:
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个字节,直到我到达最后一次迭代,其中重新记录的字节小于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;
}
}
答案 0 :(得分:4)
首先,您正在阅读字符,而不是字节。这有很大的不同。
至于为什么它不一定会同时读取所有内容:也许没有那么多可用的数据,并且StreamReader
已经决定给你什么,而不是阻止不确定的时间填补你的缓冲区。完全有权这样做。
这是来自本地文件还是来自网络?通常,本地文件操作比网络下载更有可能填充缓冲区,但无论哪种方式,您都不应该依赖于填充的缓冲区。如果它是一个“文件”(即使用FileStream
读取)但它碰巧坐在网络共享上...好吧,据我所知这是一个灰色区域:)它是一个流 - 以这种方式对待它。 / p>
答案 1 :(得分:3)
这取决于您正在阅读的实际流。如果这是文件流,我想它不太可能获得“部分”数据。但是,如果您从网络流中读取数据,则必须预期数据会以不同长度的数据块形式出现。
答案 2 :(得分:2)
来自文档:http://msdn.microsoft.com/en-us/library/9kstw824
使用Read方法时,使用缓冲区效率更高 与流的内部缓冲区大小相同,其中 内部缓冲区设置为您想要的块大小,并始终读取 小于块大小。如果内部缓冲区的大小是 在构造流时未指定,其默认大小为 4 千字节(4096字节)。如果你操纵的位置 读取数据后的底层流进入缓冲区的位置 底层流可能与内部的位置不匹配 缓冲。要重置内部缓冲区,请调用DiscardBufferedData 方法;但是,这种方法会降低性能并应该调用 只有在绝对必要的时候。
因此,对于返回值,文档说:
已读取的字符数,如果在结尾时为0 的&GT;流,没有数据被读取。数量将小于或等于 计数参数,取决于数据是否可用 在溪流内。
或者,总结一下 - 你的缓冲区和底层缓冲区的大小不一样,因此你得到缓冲区的部分填充,因为底层的缓冲区还没有被填满。