StreamReader.ReadLine 将陷入无限循环
StreamReader.ReadLine will hang in an infinite loop
我有一个简单的程序可以使用 StreamReader 读取文件并逐行处理它。但我正在阅读的文件有时可能位于网络文件夹中。我在对这样的文件进行一些测试时遇到过,如果在我阅读时网络连接在某个时候丢失,它将一次又一次地停留在同一行中,并通过产生与结果相同的行而无限循环来自 stream.ReadLine().
当文件句柄从流本身不可用时,有什么方法可以找到吗?当文件句柄从 StreamReader 丢失时,我期待 FileNotAvailableException 类型的异常会触发。
这是我的代码片段...
string file = @"Z://1601120903.csv"; //Network file
string line;
StringBuilder stb = new StringBuilder();
StreamReader stream = new StreamReader(file, Encoding.UTF8, true, 1048576);
do
{
line = stream.ReadLine();
// Do some work here
} while (line != "");
与null
比较而不是空字符串:
https://msdn.microsoft.com/en-us/library/system.io.streamreader.readline(v=vs.110).aspx
Return Value Type: System.String The next line from the input stream,
or null if the end of the input stream is reached.
do
{
line = stream.ReadLine();
// Do some work here
} while (line != null);
但是,更好的方法是让 .Net 为您完成工作(逐行读取文件)并放弃所有读取器:
foreach (String line in File.ReadLines(file)) {
// Do some work here
}
假设文件在您阅读时不应更改并且文件不大,您可能需要考虑将其复制到临时文件(本地),然后在不受干扰的情况下对其进行处理。
如果您想获取您到达的地点的索引,这可能会有所帮助:
How to know position(linenumber) of a streamreader in a textfile?
如果用 while
循环编写:
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
Source
正确方法 1 (EndOfStream) :
using(StreamReader sr = new StreamReader(...)) {
while(!sr.EndOfStream) {
string line = sr.ReadLine();
Console.WriteLine(line);
}
}
正确方法 2 (Peek)
using(StreamReader sr = new StreamReader(...)) {
while(sr.Peek() >= 0) {
string line = sr.ReadLine();
}
}
注意:将空字符串威胁为文件结尾是不正确的。
if the network connection lost at some point while I am reading,
it'll stay in the same line again and again looping in an infinite
loop by resulting the same line as the result from stream.ReadLine()
我现在已经检查了这种情况 - 在这种情况下应该抛出 System.IO.IOException
("The network path was not found."}。
Wrapping this with a try catch block will not fix my problem, will it?
这种情况下可以按如下方式打破阅读:
string line;
do {
try {
line = sr.ReadLine();
// Do some work here
}
catch(System.IO.IOException) {
break;
}
} while(line != null);
另一种方法是使用 File.ReadAllLines(),它将负责打开文件并读取所有行并关闭文件,并且还可以处理网络连接丢失时的情况。
var lines = File.ReadAllLines("Z://1601120903.csv");
foreach(line in lines)
{
// Do some work
}
如果您的流是 NetworkStream,ReadLine 方法将无限期地从流中获取更多内容(如果到达末尾)。我认为,根据 StreamReader 文档,它被设计为仅适用于本地文件流。在这种情况下,您可以直接从 NetworkStream 中读取字节。
我有一个简单的程序可以使用 StreamReader 读取文件并逐行处理它。但我正在阅读的文件有时可能位于网络文件夹中。我在对这样的文件进行一些测试时遇到过,如果在我阅读时网络连接在某个时候丢失,它将一次又一次地停留在同一行中,并通过产生与结果相同的行而无限循环来自 stream.ReadLine().
当文件句柄从流本身不可用时,有什么方法可以找到吗?当文件句柄从 StreamReader 丢失时,我期待 FileNotAvailableException 类型的异常会触发。
这是我的代码片段...
string file = @"Z://1601120903.csv"; //Network file
string line;
StringBuilder stb = new StringBuilder();
StreamReader stream = new StreamReader(file, Encoding.UTF8, true, 1048576);
do
{
line = stream.ReadLine();
// Do some work here
} while (line != "");
与null
比较而不是空字符串:
https://msdn.microsoft.com/en-us/library/system.io.streamreader.readline(v=vs.110).aspx
Return Value Type: System.String The next line from the input stream, or null if the end of the input stream is reached.
do
{
line = stream.ReadLine();
// Do some work here
} while (line != null);
但是,更好的方法是让 .Net 为您完成工作(逐行读取文件)并放弃所有读取器:
foreach (String line in File.ReadLines(file)) {
// Do some work here
}
假设文件在您阅读时不应更改并且文件不大,您可能需要考虑将其复制到临时文件(本地),然后在不受干扰的情况下对其进行处理。
如果您想获取您到达的地点的索引,这可能会有所帮助: How to know position(linenumber) of a streamreader in a textfile?
如果用 while
循环编写:
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
Source
正确方法 1 (EndOfStream) :
using(StreamReader sr = new StreamReader(...)) {
while(!sr.EndOfStream) {
string line = sr.ReadLine();
Console.WriteLine(line);
}
}
正确方法 2 (Peek)
using(StreamReader sr = new StreamReader(...)) {
while(sr.Peek() >= 0) {
string line = sr.ReadLine();
}
}
注意:将空字符串威胁为文件结尾是不正确的。
if the network connection lost at some point while I am reading, it'll stay in the same line again and again looping in an infinite loop by resulting the same line as the result from stream.ReadLine()
我现在已经检查了这种情况 - 在这种情况下应该抛出 System.IO.IOException
("The network path was not found."}。
Wrapping this with a try catch block will not fix my problem, will it?
这种情况下可以按如下方式打破阅读:
string line;
do {
try {
line = sr.ReadLine();
// Do some work here
}
catch(System.IO.IOException) {
break;
}
} while(line != null);
另一种方法是使用 File.ReadAllLines(),它将负责打开文件并读取所有行并关闭文件,并且还可以处理网络连接丢失时的情况。
var lines = File.ReadAllLines("Z://1601120903.csv");
foreach(line in lines)
{
// Do some work
}
如果您的流是 NetworkStream,ReadLine 方法将无限期地从流中获取更多内容(如果到达末尾)。我认为,根据 StreamReader 文档,它被设计为仅适用于本地文件流。在这种情况下,您可以直接从 NetworkStream 中读取字节。