StreamReader.ReadLine将挂起无限循环

时间:2016-02-10 15:01:00

标签: c# .net streamreader

我有一个简单的程序来使用StreamReader读取文件并逐行处理。但我正在阅读的文件有时可能位于网络文件夹中。我在使用这样的文件进行一些测试时遇到过,如果网络连接在我正在读取的某个时刻丢失,它将再次保持在同一行,并且在无限循环中循环,产生与结果相同的行来自stream.ReadLine()。

当流本身没有fileHandle时,我能找到一种方法吗?我期待FileReotAvailableException类型的异常会在StreamReader丢失文件句柄时触发。

这是我的代码段......

        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 != "");

6 个答案:

答案 0 :(得分:17)

null比较空字符串

https://msdn.microsoft.com/en-us/library/system.io.streamreader.readline(v=vs.110).aspx

  

返回值类型:System.String输入流的下一行,   如果到达输入流的末尾,则返回null。

    do
    {
        line = stream.ReadLine();
        // Do some work here
    } while (line != null);

然而,更好的方法是让.Net为您完成工作(逐行文件阅读)并放弃所有读者:

  foreach (String line in File.ReadLines(file)) {
    // Do some work here
  }

答案 1 :(得分:7)

正确方法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();
    }
}

注意:将空字符串威胁为文件末尾是不正确的。

  

如果在我阅读的时候网络连接丢失了,   它会一次又一次地停留在同一条线上,并且无限循环   循环得到与stream.ReadLine()

的结果相同的行

我现在已经检查了这个场景 - 在这种情况下应该抛出System.IO.IOException(“未找到网络路径。”}。

  

使用try catch块包装它不会解决我的问题,是吗?

在这种情况下,您可以按如下方式打破阅读:

string line;
do {
    try {
        line = sr.ReadLine();
        // Do some work here
    }
    catch(System.IO.IOException) {
        break; 
    }
} while(line != null);

答案 2 :(得分:3)

如果你用while - 循环编写它:

while ((line = sr.ReadLine()) != null)
{
    Console.WriteLine(line);
}

Source

答案 3 :(得分:1)

另一种方法是使用File.ReadAllLines(),它将负责打开文件并读取所有行并关闭文件,并且还可以处理网络连接丢失时的情况。

var lines = File.ReadAllLines("Z://1601120903.csv");

foreach(line in lines)
{
 // Do some work
}

答案 4 :(得分:0)

假设文件在阅读时不应该发生变化而且不是很大,您可能需要考虑将其复制到临时文件(本地),然后在不受干扰的情况下对其进行处理。

如果您想获得您到达的地方的索引,这可能会有所帮助: How to know position(linenumber) of a streamreader in a textfile?

答案 5 :(得分:0)

如果流是NetworkStream,则ReadLine方法将无限期地从流中获取更多内容(如果最终到达)。我认为,根据StreamReader文档,它只能与本地文件流一起使用。在这种情况下,您可以直接从NetworkStream读取字节。

https://docs.microsoft.com/pt-br/dotnet/api/system.net.sockets.networkstream.read?view=netcore-3.1#System_Net_Sockets_NetworkStream_Read_System_Span_System_Byte_ _