Answers:
严重迟来的编辑:如果您使用的是.NET 4.0或更高版本
的File
类有一个新的ReadLines
,其懒惰地列举线而不是贪婪地读取它们全部纳入等的阵列的方法ReadAllLines
。因此,现在您可以同时拥有效率和简洁性:
var lineCount = File.ReadLines(@"C:\file.txt").Count();
原始答案
如果您不太担心效率,可以简单地写:
var lineCount = File.ReadAllLines(@"C:\file.txt").Length;
对于更有效的方法,您可以执行以下操作:
var lineCount = 0;
using (var reader = File.OpenText(@"C:\file.txt"))
{
while (reader.ReadLine() != null)
{
lineCount++;
}
}
编辑:回应有关效率的问题
我说第二个效率更高的原因是关于内存使用情况,不一定是速度。第一个将文件的全部内容加载到一个数组中,这意味着它必须至少分配与文件大小相同的内存。第二个仅一次循环一行,因此它永远不必一次分配多于一行的内存。对于小文件来说,这并不是很重要,但是对于大文件来说,这可能是个问题(例如,如果您尝试在32位系统上查找4GB文件中的行数,那么根本不够用)用户模式地址空间来分配这么大的数组)。
就速度而言,我不希望其中有很多。ReadAllLines可能在内部进行了一些优化,但另一方面,它可能不得不分配大量的内存。我猜想对于小文件,ReadAllLines可能会更快,但是对于大文件,ReadAllLines可能会慢得多。尽管唯一的方法是使用秒表或代码分析器对其进行测量。
ReadLines().Count()
您需要using System.Linq
在包含中添加一个。要求添加它似乎很不直观,所以这就是我提到它的原因。如果您使用的是Visual Studio,则可能会自动为您完成此添加。
如果简单地说,您是说容易破译但效率低下的几行代码?
string[] lines = System.IO.File.RealAllLines($filename);
int cnt = lines.Count();
这可能是知道多少行的最快方法。
您也可以这样做(取决于您是否在其中缓冲)
#for large files
while (...reads into buffer){
string[] lines = Regex.Split(buffer,System.Enviorment.NewLine);
}
还有许多其他方法,但是以上可能之一是您将要使用的方法。
读取文件本身需要花费一些时间,垃圾回收结果是另一个问题,因为您读取整个文件只是为了计算换行符,
在某个时候,无论是框架还是代码,都必须读取文件中的字符。这意味着您必须打开文件并将其读入内存(如果文件很大),这将可能成为问题,因为需要对内存进行垃圾回收。
这是建议的解决方案,因为它一次读取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;
}
在上方可以看到,底层框架一次也读取一行字符,因为您需要读取所有字符才能看到换行符。
如果将它描述为完成的Nima海湾,您会发现这是一种相当快速有效的方法。
try {
string path = args[0];
FileStream fh = new FileStream(path, FileMode.Open, FileAccess.Read);
int i;
string s = "";
while ((i = fh.ReadByte()) != -1)
s = s + (char)i;
//its for reading number of paragraphs
int count = 0;
for (int j = 0; j < s.Length - 1; j++) {
if (s.Substring(j, 1) == "\n")
count++;
}
Console.WriteLine("The total searches were :" + count);
fh.Close();
} catch(Exception ex) {
Console.WriteLine(ex.Message);
}