Jawaban:
Sunting terlambat: Jika Anda menggunakan .NET 4.0 atau lebih baru
The File
kelas memiliki baru ReadLines
metode yang malas menyebutkan garis daripada rakus membaca mereka semua ke dalam array seperti ReadAllLines
. Jadi sekarang Anda dapat memiliki efisiensi dan keringkasan dengan:
var lineCount = File.ReadLines(@"C:\file.txt").Count();
Jawaban Asli
Jika Anda tidak terlalu peduli dengan efisiensi, Anda cukup menulis:
var lineCount = File.ReadAllLines(@"C:\file.txt").Length;
Untuk metode yang lebih efisien, Anda dapat melakukan:
var lineCount = 0;
using (var reader = File.OpenText(@"C:\file.txt"))
{
while (reader.ReadLine() != null)
{
lineCount++;
}
}
Sunting: Menanggapi pertanyaan tentang efisiensi
Alasan saya mengatakan yang kedua lebih efisien adalah tentang penggunaan memori, belum tentu kecepatan. Yang pertama memuat seluruh isi file ke dalam array yang berarti harus mengalokasikan setidaknya memori sebanyak ukuran file. Baris kedua hanya memotong satu baris pada satu waktu sehingga tidak perlu mengalokasikan lebih dari satu memori dalam satu waktu. Ini tidak begitu penting untuk file kecil, tetapi untuk file yang lebih besar itu bisa menjadi masalah (jika Anda mencoba dan menemukan jumlah baris dalam file 4GB pada sistem 32-bit, misalnya, di mana hanya ada tidak cukup ruang alamat mode pengguna untuk mengalokasikan array sebesar ini).
Dalam hal kecepatan, saya tidak berharap ada banyak hal di dalamnya. Ada kemungkinan bahwa ReadAllLines memiliki beberapa optimasi internal, tetapi di sisi lain itu mungkin harus mengalokasikan sejumlah besar memori. Saya menduga bahwa ReadAllLines mungkin lebih cepat untuk file kecil, tetapi secara signifikan lebih lambat untuk file besar; meskipun satu-satunya cara untuk mengetahuinya adalah dengan mengukurnya dengan Stopwatch atau kode profiler.
ReadLines().Count()
Anda harus menambahkan using System.Linq
ke dalam menyertakan Anda. Tampaknya tidak intuitif untuk memerlukan penambahan itu, jadi itu sebabnya saya menyebutkannya. Jika Anda menggunakan Visual Studio, kemungkinan penambahan ini dilakukan untuk Anda secara otomatis.
Jika dengan mudah maksud Anda adalah baris kode yang mudah diuraikan tetapi per kesempatan tidak efisien?
string[] lines = System.IO.File.RealAllLines($filename);
int cnt = lines.Count();
Itu mungkin cara tercepat untuk mengetahui berapa banyak baris.
Anda juga bisa melakukannya (tergantung apakah Anda melakukan buffering)
#for large files
while (...reads into buffer){
string[] lines = Regex.Split(buffer,System.Enviorment.NewLine);
}
Ada banyak cara lain tetapi salah satu di atas mungkin adalah apa yang akan Anda gunakan.
Anda dapat dengan cepat membacanya, dan menambah penghitung, cukup gunakan satu lingkaran untuk menambah, tidak melakukan apa-apa dengan teks.
Membaca file dengan sendirinya membutuhkan waktu, pengumpulan sampah adalah masalah lain saat Anda membaca seluruh file hanya untuk menghitung karakter baris baru,
Pada titik tertentu, seseorang harus membaca karakter dalam file, terlepas dari apakah kerangka ini atau apakah itu kode Anda. Ini berarti Anda harus membuka file dan membacanya ke dalam memori jika file besar ini berpotensi menjadi masalah karena memori perlu dikumpulkan sampah.
Nima Ara membuat analisis bagus yang bisa Anda pertimbangkan
Berikut adalah solusi yang diusulkan, karena membaca 4 karakter sekaligus, menghitung karakter umpan baris dan menggunakan kembali alamat memori yang sama lagi untuk perbandingan karakter berikutnya.
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;
}
Di atas Anda dapat melihat bahwa suatu baris dibaca satu karakter pada suatu waktu juga oleh kerangka kerja yang mendasarinya karena Anda perlu membaca semua karakter untuk melihat umpan baris.
Jika Anda memprofilkannya sebagai selesai Nima Anda akan melihat bahwa ini adalah cara yang agak cepat dan efisien untuk melakukan ini.
Opsi yang layak, dan yang telah saya gunakan secara pribadi, adalah menambahkan header Anda sendiri ke baris pertama file. Saya melakukan ini untuk format model khusus untuk game saya. Pada dasarnya, saya memiliki alat yang mengoptimalkan file .obj saya, menyingkirkan omong kosong yang tidak saya butuhkan, mengubahnya menjadi tata letak yang lebih baik, dan kemudian menulis jumlah total garis, wajah, normals, simpul, dan tekstur UV pada baris pertama. Data itu kemudian digunakan oleh berbagai buffer array ketika model dimuat.
Ini juga berguna karena Anda hanya perlu mengulang-ulang file sekali untuk memuatnya, daripada sekali menghitung baris, dan lagi untuk membaca data ke buffer yang Anda buat.
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);
}
Anda dapat meluncurkan " wc .exe" yang dapat dieksekusi (dilengkapi dengan UnixUtils dan tidak perlu instalasi) berjalan sebagai proses eksternal. Ini mendukung metode penghitungan baris yang berbeda (seperti unix vs mac vs windows).