我有一个简单的程序来使用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 != "");
答案 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)
答案 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读取字节。