是否有一种简单的方法来编程确定文本文件中的行数?


当前回答

如果你说的简单是指易于破译但效率很低的代码行?

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

还有许多其他的方法,但上面的一种可能是你会选择的。

其他回答

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

计算回车/换行次数。我相信在unicode中它们仍然分别是0x000D和0x000A。这样你就可以根据自己的意愿来决定是否要同时处理两个角色

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

在某些情况下,某人将不得不读取文件中的字符,无论这是框架还是您的代码。这意味着您必须打开文件并将其读入内存,如果文件很大,这将潜在地成为一个问题,因为内存需要进行垃圾收集。

尼玛·阿拉做了一个很好的分析,你可以考虑一下

下面是提出的解决方案,因为它一次读取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;
}

上面你可以看到,一行是由底层框架一次读取一个字符,因为你需要读取所有字符来查看换行。

如果你侧写它为完成海湾尼玛,你会看到这是一个相当快速和有效的方式来做这件事。

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

int count = 0;
string line;
TextReader reader = new StreamReader("file.txt");
while ((line = reader.ReadLine()) != null)
{
  count++;
}
reader.Close();
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);
}