是否有一种简单的方法可以通过编程方式确定文本文件中的行数?

有帮助吗?

解决方案

严重迟到编辑:如果您使用的是.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可能更快,但对于大文件来说速度要慢得多;虽然唯一的方法是使用秒表或代码分析器来测量它。

其他提示

最简单:

int lines = File.ReadAllLines("myfile").Length;

这会占用更少的内存,但可能需要更长的时间

int count = 0;
string line;
TextReader reader = new StreamReader("file.txt");
while ((line = reader.ReadLine()) != null)
{
  count++;
}
reader.Close();

如果简单的话,你的意思是一行代码很容易破译,但机会效率低下?

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);
}

还有其他许多方法,但上述其中一种可能就是你要用的。

你可以快速阅读它,并增加一个计数器,只需使用一个循环来增加,不对文本做任何事情。

计算回车/换行。我相信unicode它们仍然分别是0x000D和0x000A。这样你可以像你想要的那样高效或低效,并决定你是否必须处理这两个角色

一个可行的选项,也就是我个人使用的选项,就是将自己的标题添加到文件的第一行。我为我的游戏制作了自定义模型格式。基本上,我有一个工具可以优化我的.obj文件,摆脱我不需要的垃圾,将它们转换为更好的布局,然后写出线条,面,法线,顶点和纹理UV的总数第一行。然后,在加载模型时,各种数组缓冲区将使用该数据。

这也很有用,因为您只需要遍历文件一次以加载它,而不是一次计算行数,再次将数据读入您创建的缓冲区。

读取文件本身需要花费一些时间,收集结果的垃圾是另一个问题,因为你读取整个文件只是为了计算换行符,

在某些时候,某人将不得不阅读文件中的字符,无论是框架还是代码。这意味着如果文件很大,你必须打开文件并将其读入内存,这可能是一个问题,因为内存需要进行垃圾回收。

Nima Ara做了一个很好的分析你可以考虑一下

这是建议的解决方案,因为它一次读取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;
}

上面你可以看到一行一行也被一个字符读取,因为你需要读取所有字符以查看换行符。

如果您将其描述为完成了Bay 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);
}         

您可以启动“ wc .exe”可执行文件(附带 UnixUtils 并且不需要安装)作为外部进程运行。它支持不同的行数方法(如unix vs mac vs windows)。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top