确定文本文件中的行数

时间:2008-09-23 07:25:31

标签: c# input text-files

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

11 个答案:

答案 0 :(得分:365)

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

答案 1 :(得分:13)

最简单:

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

答案 2 :(得分:8)

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

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

答案 3 :(得分:5)

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

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 :(得分:2)

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

答案 5 :(得分:1)

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

答案 6 :(得分:1)

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

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

答案 7 :(得分:1)

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

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

Nima Ara made a nice analysis that you might take into consideration

这是建议的解决方案,因为它一次读取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,您会发现这是一种相当快速有效的方法。

答案 8 :(得分:0)

使用此:

    int get_lines(string file)
    {
        var lineCount = 0;
        using (var stream = new StreamReader(file))
        {
            while (stream.ReadLine() != null)
            {
                lineCount++;
            }
        }
        return lineCount;
    }

答案 9 :(得分:-1)

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

答案 10 :(得分:-2)

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