这样做有什么问题吗?
int i = new StreamReader("file.txt").ReadToEnd().Split(new char[] {'\n'}).Length
答案 0 :(得分:46)
您发布的方法并不是特别好。让我们分开:
// new StreamReader("file.txt").ReadToEnd().Split(new char[] {'\n'}).Length
// becomes this:
var file = new StreamReader("file.txt").ReadToEnd(); // big string
var lines = file.Split(new char[] {'\n'}); // big array
var count = lines.Count;
你实际上在内存中保存了这个文件两次:一次读取所有行,一次将其拆分为数组。垃圾收集器讨厌这个。
如果您喜欢一个衬垫,可以编写System.IO.File.ReadAllLines(filePath).Length
,但仍然可以在数组中检索整个文件。如果你不打算坚持阵列就没有意义。
更快的解决方案是:
int TotalLines(string filePath)
{
using (StreamReader r = new StreamReader(filePath))
{
int i = 0;
while (r.ReadLine() != null) { i++; }
return i;
}
}
上面的代码在任何给定时间保存(最多)内存中的一行文本。只要线条相对较短,它就会高效。
答案 1 :(得分:6)
嗯,这样做的问题是,在大文件上执行此操作时,您会分配 lot 。
我宁愿逐行读取文件并手动递增计数器。这可能不是单行,但它的内存效率更高。
或者,您可以以偶数大小的块加载数据并计算这些中的换行符。这可能是最快的方式。
答案 2 :(得分:4)
如果你正在寻找一个简短的解决方案,我可以给你一个单行程序,至少可以让你免于分裂结果:
int i = File.ReadAllLines("file.txt").Count;
但是这与将原始大文件读入内存存在同样的问题。您应该真正使用流读取器并在读取时计算换行符,直到到达文件末尾。
答案 3 :(得分:2)
当然 - 它将整个流读入内存。这很简洁,但我今天可以创建一个文件,但这很难实现。
一次阅读一个角色,并在换行符上增加计数。
编辑 - 经过一些快速研究 如果你想要简洁并想要那种闪亮的新通用感觉,请考虑一下:public class StreamEnumerator : IEnumerable<char>
{
StreamReader _reader;
public StreamEnumerator(Stream stm)
{
if (stm == null)
throw new ArgumentNullException("stm");
if (!stm.CanSeek)
throw new ArgumentException("stream must be seekable", "stm");
if (!stm.CanRead)
throw new ArgumentException("stream must be readable", "stm");
_reader = new StreamReader(stm);
}
public IEnumerator<char> GetEnumerator()
{
int c = 0;
while ((c = _reader.Read()) >= 0)
{
yield return (char)c;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
定义了一个允许您枚举流的新类,然后您的计数代码可能如下所示:
StreamEnumerator chars = new StreamEnumerator(stm);
int lines = chars.Count(c => c == '\n');
它为你提供了一个很好的简洁lambda表达式(或多或少)你想要的东西。
我还是喜欢Old Skool:
public static int CountLines(Stream stm)
{
StreamReader _reader = new StreamReader(stm);
int c = 0, count = 0;
while ((c = _reader.Read()) != -1)
{
if (c == '\n')
{
count++;
}
}
return count;
}
注意:环境.NewLine版本留给读者练习
答案 4 :(得分:1)
Mayby这个?
string file = new StreamReader("YourFile.txt").ReadToEnd();
string[] lines = file.Split('\n');
int countOfLines = lines.GetLength(0));
答案 5 :(得分:0)
这应该可以解决问题:
using System.Linq;
....
int i = File.ReadLines(file).Count();
答案 6 :(得分:-1)
假设文件存在且您可以打开它,那将会有效。
它不是非常易读或安全......