c#如何计算文本文件中的行数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/496663/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
c# how do I count lines in a textfile
提问by Brad
any problems with doing this?
这样做有什么问题吗?
int i = new StreamReader("file.txt").ReadToEnd().Split(new char[] {'\n'}).Length
采纳答案by Juliet
The method you posted isn't particularly good. Lets break this apart:
你贴的方法不是特别好。让我们分解一下:
// 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;
You're actually holding this file in memory twice: once to read all the lines, once to split it into an array. The garbage collector hates that.
您实际上将这个文件保存在内存中两次:一次读取所有行,一次将其拆分为数组。垃圾收集器讨厌这样。
If you like one liners, you can write System.IO.File.ReadAllLines(filePath).Length
, but that still retrieves the entire file in an array. There's no point doing that if you aren't going to hold onto the array.
如果你喜欢一个衬垫,你可以写System.IO.File.ReadAllLines(filePath).Length
,但这仍然会检索数组中的整个文件。如果您不打算保留阵列,那么这样做是没有意义的。
A faster solution would be:
更快的解决方案是:
int TotalLines(string filePath)
{
using (StreamReader r = new StreamReader(filePath))
{
int i = 0;
while (r.ReadLine() != null) { i++; }
return i;
}
}
The code above holds (at most) one line of text in memory at any given time. Its going to be efficient as long as the lines are relatively short.
上面的代码在任何给定时间(最多)在内存中保存一行文本。只要线路相对较短,它就会很有效率。
回答by Konrad Rudolph
Well, the problem with doing this is that you allocate a lotof memory when doing this on large files.
好吧,这样做的问题是在对大文件执行此操作时分配了大量内存。
I would rather read the file line by line and manually increment a counter. This may not be a one-liner but it's much more memory-efficient.
我宁愿逐行读取文件并手动增加计数器。这可能不是单行,但它的内存效率更高。
Alternatively, you may load the data in even-sized chunks and count the line breaks in these. This is probably the fastest way.
或者,您可以以均匀大小的块加载数据并计算其中的换行符。这可能是最快的方式。
回答by plinth
Sure - it reads the entire stream into memory. It's terse, but I can create a file today that will fail this hard.
当然 - 它将整个流读入内存。这很简洁,但我今天可以创建一个文件,但它会失败。
Read a character at a time and increment your count on newline.
一次读取一个字符并增加换行符的计数。
EDIT - after some quick research If you want terse and want that shiny new generic feel, consider this:
编辑 - 经过一些快速研究如果您想要简洁并想要那种闪亮的新通用感觉,请考虑:
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();
}
}
which defines a new class which allows you to enumerate over streams, then your counting code can look like this:
它定义了一个允许您枚举流的新类,然后您的计数代码可以如下所示:
StreamEnumerator chars = new StreamEnumerator(stm);
int lines = chars.Count(c => c == '\n');
which gives you a nice terse lambda expression to do (more or less) what you want.
这为您提供了一个简洁的 lambda 表达式来执行(或多或少)您想要的操作。
I still prefer the Old Skool:
我还是更喜欢 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;
}
NB: Environment.NewLine version left as an exercise for the reader
注意:Environment.NewLine 版本留给读者作为练习
回答by Austin Salonen
Assuming the file exists and you can open it, that will work.
假设文件存在并且您可以打开它,那将起作用。
It's not very readable or safe...
它不是很可读或安全......
回答by Joel Coehoorn
If you're looking for a short solution, I can give you a one-liner that at least saves you from having to split the result:
如果您正在寻找一个简短的解决方案,我可以为您提供一个单行代码,至少可以让您不必拆分结果:
int i = File.ReadAllLines("file.txt").Count;
But that has the same problems of reading a large file into memory as your original. You should really use a streamreader and count the line breaks as you read them until you reach the end of the file.
但这与将大文件读入内存的问题相同。您应该真正使用流阅读器并在阅读时计算换行符,直到到达文件末尾。
回答by Rinepim
Mayby this?
梅比这个?
string file = new StreamReader("YourFile.txt").ReadToEnd();
string[] lines = file.Split('\n');
int countOfLines = lines.GetLength(0));
回答by dimaaan
That should do the trick:
这应该够了吧:
using System.Linq;
....
int i = File.ReadLines(file).Count();