2008-09-23 3 views

ответ

318

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

Edit: В ответ на вопросы об эффективности

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

С точки зрения скорости я не ожидал, что там будет много. Возможно, что ReadAllLines имеет некоторые внутренние оптимизации, но, с другой стороны, возможно, придется выделить массивный кусок памяти. Я предполагаю, что ReadAllLines может быть быстрее для небольших файлов, но значительно медленнее для больших файлов; хотя единственный способ сказать - измерить его с помощью секундомера или профайлера кода.

+0

Почему второй метод менее эффективен, чем первый? Это не очевидно из кода. – Sklivvz 2008-09-23 07:39:18

+0

Мое внутреннее чувство будет первым, может быть, быстрее, но это просто предположение – johnc 2008-09-23 07:46:36

+2

Небольшое примечание: поскольку String является ссылочным типом, массив будет размером с количеством строк x размером указателя, но вы правы что он все равно должен хранить текст, а каждая строка - как один объект String. – 2008-09-23 11:08:09

2

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

13

Самым простой:

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

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

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

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

8

Это будет использовать меньше памяти, но, вероятно, займет больше времени

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

Вы можете запустить «wc .exe» исполняемый файл (поставляется с UnixUtils и не требует установки) работать в качестве внешнего процесса. Он поддерживает различные методы подсчета строк (например, unix vs mac vs windows).

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

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

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

Смежные вопросы