Yanıtlar:
Cidden gecikmiş düzenleme: .NET 4.0 veya üstünü kullanıyorsanız
File
Sınıfı, yeni sahiptir ReadLines
lazily iştahla gibi bir diziye hepsini okuma yerine hatları sıralar yöntem ReadAllLines
. Böylece şimdi hem verime hem de kısaca sahip olabilirsiniz:
var lineCount = File.ReadLines(@"C:\file.txt").Count();
Orijinal Yanıt
Verimlilikten çok rahatsız değilseniz, şunları yazabilirsiniz:
var lineCount = File.ReadAllLines(@"C:\file.txt").Length;
Daha verimli bir yöntem için şunları yapabilirsiniz:
var lineCount = 0;
using (var reader = File.OpenText(@"C:\file.txt"))
{
while (reader.ReadLine() != null)
{
lineCount++;
}
}
Düzenleme: Verimlilik ile ilgili sorulara yanıt olarak
İkincisinin daha verimli olduğunu söylememin sebebi, hız değil, bellek kullanımı ile ilgilidir. Birincisi, dosyanın tüm içeriğini bir diziye yükler; bu, dosyanın boyutu kadar en az bellek ayırması gerektiği anlamına gelir. İkincisi sadece bir seferde bir satır döngüye girer, bu yüzden asla bir seferde birden fazla satırın belleğini ayırmak zorunda kalmaz. Bu, küçük dosyalar için o kadar önemli değildir, ancak daha büyük dosyalar için bir sorun olabilir (örneğin, 32 bitlik bir sistemde 4 GB'lık bir dosyadaki satır sayısını bulmaya çalışırsanız, örneğin, yeterli olmayan kullanıcı modu adres alanı bu kadar büyük bir dizi ayırmak için).
Hız açısından, içinde çok fazla bir şey olmasını beklemiyordum. ReadAllLines'in bazı dahili optimizasyonları olabilir, ancak öte yandan, büyük bir bellek yığını tahsis etmesi gerekebilir. Ben ReadAllLines küçük dosyalar için daha hızlı, ancak büyük dosyalar için önemli ölçüde daha yavaş olabilir sanırım; ancak anlatmanın tek yolu bunu bir Kronometre veya kod profiler ile ölçmek olacaktır.
ReadLines().Count()
için eklentilerinize a eklemeniz gerekecektir using System.Linq
. Bu eklemeyi istemek oldukça sezgisel görünmüyordu, bu yüzden bundan bahsediyorum. Visual Studio kullanıyorsanız, bu ekleme sizin için otomatik olarak yapılır.
Kolayca deşifre etmek kolay ama şans başına verimsiz bir kod satırları demek?
string[] lines = System.IO.File.RealAllLines($filename);
int cnt = lines.Count();
Muhtemelen kaç satır olduğunu bilmenin en hızlı yolu budur.
Ayrıca şunları yapabilirsiniz (arabelleğe alıp almadığınıza bağlı olarak)
#for large files
while (...reads into buffer){
string[] lines = Regex.Split(buffer,System.Enviorment.NewLine);
}
Başka sayısız yol var ama yukarıdakilerden biri muhtemelen gideceğiniz şey.
Hızlı bir şekilde okuyabilir ve bir sayacı artırabilirsiniz, sadece artırmak için bir döngü kullanın, metinle hiçbir şey yapmayın.
Bir dosyayı kendi başına okumak biraz zaman alır, sonucu toplamak, yalnızca satırsonu karakterlerini saymak için tüm dosyayı okurken başka bir sorundur,
Bir noktada, birisi bu çerçevenin veya kodunuzun olup olmadığına bakılmaksızın dosyadaki karakterleri okumak zorunda kalacaktır. Bu, dosyayı açmanız ve dosya büyükse belleğe okumanız gerektiği anlamına gelir; bu, belleğin çöp toplanması gerektiğinden potansiyel olarak bir sorun olacaktır.
Nima Ara, dikkate alabileceğiniz güzel bir analiz yaptı
Burada önerilen çözüm, her seferinde 4 karakter okuduğundan, satır besleme karakterini sayar ve bir sonraki karakter karşılaştırması için aynı bellek adresini tekrar kullanır.
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;
}
Yukarıda, satır beslemesini görmek için tüm karakterleri okumanız gerektiğinden, bir satırın altta yatan çerçeve tarafından her seferinde bir karakter okunduğunu görebilirsiniz.
Eğer bunu bay Nima olarak yapmışsanız, bunun bunu yapmanın oldukça hızlı ve etkili bir yolu olduğunu görürsünüz.
Geçerli bir seçenek ve kişisel olarak kullandığım seçenek, dosyanın ilk satırına kendi başlığınızı eklemek olacaktır. Bunu oyunum için özel bir model formatı için yaptım. Temel olarak, .obj dosyalarımı optimize eden, ihtiyacım olan saçmalıklardan kurtulan, daha iyi bir düzene dönüştüren ve daha sonra toplam satır, yüz, normal, köşe ve doku UV'lerini yazan bir aracım var ilk satır. Bu veriler daha sonra model yüklendiğinde çeşitli dizi arabellekleri tarafından kullanılır.
Bu da kullanışlıdır çünkü dosyayı yüklemek için sadece bir kez, satırları saymak yerine ve verileri oluşturduğunuz arabelleklere tekrar okumak için döngü yapmanız gerekir.
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" yürütülebilir dosyasını ( UnixUtils ile birlikte gelir ve kurulum gerektirmez) harici bir işlem olarak çalıştırabilirsiniz. Farklı satır sayısı yöntemlerini destekler (unix vs mac vs windows).