Определить количество строк в текстовом файле

Есть ли простой способ программно определить количество строк в текстовом файле?

    Серьезно запоздалое редактирование: если вы используете .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++; } } 

    Изменить: В ответ на вопросы об эффективности

    Причина, по которой я сказал, что вторая была более эффективной, касалась использования памяти, а не скорости. Первый загружает все содержимое файла в массив, что означает, что он должен выделять как минимум столько же памяти, сколько размер файла. Второе просто зацикливает по одной строке за раз, поэтому ему никогда не приходится выделять память объемом более одной строки за раз. Это не так важно для небольших файлов, но для больших файлов это может быть проблемой (если вы попытаетесь найти количество строк в файле 4 ГБ в 32-битной системе, например, там, где их просто недостаточно адресное пространство пользовательского режима для выделения большого массива).

    С точки зрения скорости я не ожидал, что там будет много. Возможно, что 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); } 

    Есть и другие многочисленные способы, но одно из вышеперечисленных – это, вероятно, то, с чем вы будете работать.

    Вы можете быстро прочитать его и увеличить счетчик, просто используйте цикл для увеличения, ничего не делая с текстом.

    подсчитайте возврат каретки / линии. Я считаю, что в юникоде они все равно 0x000D и 0x000A соответственно. таким образом, вы можете быть такими же эффективными или неэффективными, как вы хотите, и решить, имеете ли вы дело с обоими символами или нет

    Жизнеспособный вариант и тот, который я лично использовал, – это добавить свой собственный заголовок в первую строку файла. Я сделал это для пользовательского формата модели для своей игры. В принципе, у меня есть инструмент, который оптимизирует мои файлы .obj, избавляясь от дерьма, в котором я не нуждаюсь, преобразует их в лучший макет, а затем записывает общее количество строк, граней, нормалей, вершин и текстурных UVs на самая первая строка. Эти данные затем используются буферами различных массивов при загрузке модели.

    Это также полезно, потому что вам нужно только один раз пропустить файл, чтобы загрузить его, а не один раз, чтобы подсчитать строки, и снова прочитать данные в созданные буферы.

    Я пробовал разные способы и самый быстрый, если у вас очень большой файл:

     var counter = 0; using (var file = new StreamReader(@"file.txt")) { while (file.ReadLine() != null) { counter++; } } 

    Чтение файла и само по себе занимает некоторое время, garbage collection результата – это еще одна проблема, поскольку вы читаете весь файл только для подсчета символов (строк) новой строки,

    В какой-то момент кто-то должен будет прочитать символы в файле, независимо от того, является ли это каркасом или является вашим кодом. Это означает, что вы должны открыть файл и прочитать его в памяти, если файл большой, это потенциально может быть проблемой, поскольку память должна быть собрана мусором.

    Нима Ара сделал хороший анализ, который вы могли бы принять во внимание

    Вот предлагаемое решение, так как оно считывает по 4 символа за раз, подсчитывает символ линии и повторно использует тот же адрес памяти для следующего сравнения символов.

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

    Выше видно, что строка читается по одному символу за раз, а также по базовой структуре, поскольку вам нужно прочитать все символы, чтобы увидеть фид строки.

    Если вы прокомментируете это как сделанный отсек Нима, вы увидите, что это довольно быстрый и эффективный способ сделать это.

     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).

    Давайте будем гением компьютера.