Gre*_*ech 381
严重迟来的编辑:如果您使用的是.NET 4.0或更高版本
这个File类有一个新ReadLines方法,它懒洋洋地枚举行而不是贪婪地将它们全部读入数组中ReadAllLines.所以现在你可以同时兼顾效率和简洁:
var lineCount = File.ReadLines(@"C:\file.txt").Count();
Run Code Online (Sandbox Code Playgroud)
原始答案
如果你对效率不太感兴趣,你可以简单地写:
var lineCount = File.ReadAllLines(@"C:\file.txt").Length;
Run Code Online (Sandbox Code Playgroud)
要获得更有效的方法,您可以:
var lineCount = 0;
using (var reader = File.OpenText(@"C:\file.txt"))
{
while (reader.ReadLine() != null)
{
lineCount++;
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:回答有关效率的问题
我说第二个更高效的原因是关于内存使用,不一定是速度.第一个将文件的全部内容加载到一个数组中,这意味着它必须分配至少与文件大小一样多的内存.第二个只是一次循环一行,所以它不必一次分配多行的内存.这对于小文件来说并不重要,但对于较大的文件,这可能是一个问题(例如,如果您尝试在32位系统上查找4GB文件中的行数,例如,根本不够用户模式地址空间来分配这么大的数组).
在速度方面,我不希望它有很多.ReadAllLines可能有一些内部优化,但另一方面它可能需要分配大量内存.我猜对于小文件,ReadAllLines可能更快,但对于大文件来说速度要慢得多; 虽然告诉的唯一方法是使用秒表或代码分析器来测量它.
lep*_*pie 12
最简单的:
int lines = File.ReadAllLines("myfile").Length;
Run Code Online (Sandbox Code Playgroud)
这将使用更少的内存,但可能需要更长的时间
int count = 0;
string line;
TextReader reader = new StreamReader("file.txt");
while ((line = reader.ReadLine()) != null)
{
count++;
}
reader.Close();
Run Code Online (Sandbox Code Playgroud)
如果简单的话,你的意思是一行代码很容易破译但机会效率低下?
string[] lines = System.IO.File.RealAllLines($filename);
int cnt = lines.Count();
Run Code Online (Sandbox Code Playgroud)
这可能是了解多少行的最快捷方式.
你也可以这样做(取决于你是否在缓冲它)
#for large files
while (...reads into buffer){
string[] lines = Regex.Split(buffer,System.Enviorment.NewLine);
}
Run Code Online (Sandbox Code Playgroud)
还有其他许多方法,但上面的一个可能是你将要用的.
读取文件本身需要一些时间,垃圾收集结果是另一个问题,因为您读取整个文件只是为了计算换行符,
在某些时候,有人将不得不读取文件中的字符,无论这是框架还是您的代码。这意味着您必须打开文件并将其读入内存,如果文件很大,这可能会成为一个问题,因为内存需要被垃圾回收。
这是建议的解决方案,因为它一次读取 4 个字符,计算换行符并再次使用相同的内存地址进行下一个字符比较。
private const char CR = '\r';
private const char LF = '\n';
private const char NULL = (char)0;
public static long CountLinesMaybe(Stream stream)
{
Ensure.NotNull(stream, nameof(stream));
var lineCount = 0L;
var byteBuffer = new byte[1024 * 1024];
const int BytesAtTheTime = 4;
var detectedEOL = NULL;
var currentChar = NULL;
int bytesRead;
while ((bytesRead = stream.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
{
var i = 0;
for (; i <= bytesRead - BytesAtTheTime; i += BytesAtTheTime)
{
currentChar = (char)byteBuffer[i];
if (detectedEOL != NULL)
{
if (currentChar == detectedEOL) { lineCount++; }
currentChar = (char)byteBuffer[i + 1];
if (currentChar == detectedEOL) { lineCount++; }
currentChar = (char)byteBuffer[i + 2];
if (currentChar == detectedEOL) { lineCount++; }
currentChar = (char)byteBuffer[i + 3];
if (currentChar == detectedEOL) { lineCount++; }
}
else
{
if (currentChar == LF || currentChar == CR)
{
detectedEOL = currentChar;
lineCount++;
}
i -= BytesAtTheTime - 1;
}
}
for (; i < bytesRead; i++)
{
currentChar = (char)byteBuffer[i];
if (detectedEOL != NULL)
{
if (currentChar == detectedEOL) { lineCount++; }
}
else
{
if (currentChar == LF || currentChar == CR)
{
detectedEOL = currentChar;
lineCount++;
}
}
}
}
if (currentChar != LF && currentChar != CR && currentChar != NULL)
{
lineCount++;
}
return lineCount;
}
Run Code Online (Sandbox Code Playgroud)
在上面,您可以看到底层框架一次读取一个字符,因为您需要读取所有字符才能查看换行符。
如果您将其描述为 done bay Nima,您会发现这是一种相当快速和有效的方法。