जवाबों:
गंभीर रूप से बेलेट एडिट: यदि आप .NET 4.0 या बाद में उपयोग कर रहे हैं
File
वर्ग एक नया है ReadLines
विधि है जो lazily लालच से उन सब की तरह एक सरणी में पढ़ने के बजाय लाइनों विश्लेषण करता है 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++;
}
}
संपादित करें: दक्षता के बारे में सवालों के जवाब में
जिस कारण से मैंने कहा कि दूसरा अधिक कुशल था, मेमोरी उपयोग के बारे में था, जरूरी नहीं कि गति। पहले वाला फ़ाइल की संपूर्ण सामग्री को एक ऐसे सरणी में लोड करता है, जिसका अर्थ है कि उसे फ़ाइल के आकार के अनुसार कम से कम मेमोरी आवंटित करनी चाहिए। दूसरा केवल एक समय में एक पंक्ति को लूप करता है, इसलिए इसे एक बार में एक से अधिक लाइन के लायक मेमोरी आवंटित नहीं करना पड़ता है। यह छोटी फ़ाइलों के लिए महत्वपूर्ण नहीं है, लेकिन बड़ी फ़ाइलों के लिए यह एक समस्या हो सकती है (यदि आप 32-बिट सिस्टम पर 4GB फ़ाइल में लाइनों की संख्या पाते हैं, उदाहरण के लिए, जहां बस पर्याप्त नहीं है उपयोगकर्ता-मोड पते की जगह एक सरणी को आवंटित करने के लिए यह बड़ा)।
गति के संदर्भ में मुझे उम्मीद नहीं है कि इसमें बहुत कुछ होगा। यह संभव है कि ReadAllLines में कुछ आंतरिक ऑप्टिमाइज़ेशन हों, लेकिन दूसरी ओर इसे मेमोरी का एक बड़ा हिस्सा आवंटित करना पड़ सकता है। मुझे लगता है कि ReadAllLines छोटी फ़ाइलों के लिए तेज़ हो सकती है, लेकिन बड़ी फ़ाइलों के लिए काफी धीमी है; हालांकि यह बताने का एकमात्र तरीका स्टॉपवॉच या कोड प्रोफाइलर के साथ मापना होगा।
ReadLines().Count()
आपको using System.Linq
अपने शामिल करने की आवश्यकता होगी । उस जोड़ की आवश्यकता के लिए यह काफी गैर-सहज लग रहा था, इसलिए मैंने इसका उल्लेख किया। यदि आपका विजुअल स्टूडियो उपयोग कर रहा है, तो यह संभव है कि यह जोड़ आपके लिए अपने आप हो जाए।
यदि आसान से आपका मतलब कोड की ऐसी पंक्तियों से है जो आसानी से समझ में नहीं आती हैं, लेकिन प्रति मौका अक्षम हैं?
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);
}
वहाँ कई अन्य तरीके हैं, लेकिन उपरोक्त में से एक शायद वह है जिसके साथ आप जाएंगे।
आप इसे जल्दी से पढ़ सकते हैं, और एक काउंटर बढ़ा सकते हैं, बस पाठ के साथ कुछ नहीं कर, वेतन वृद्धि के लिए एक लूप का उपयोग कर सकते हैं।
किसी फ़ाइल को पढ़ना और उसके द्वारा कुछ समय लगना, परिणाम को इकट्ठा करना एक और समस्या है क्योंकि आपने पूरी फाइल को सिर्फ न्यूलाइन वर्ण (अक्षर) को गिनने के लिए पढ़ा है,
किसी बिंदु पर, किसी को फ़ाइल में वर्णों को पढ़ना होगा, भले ही यह ढांचा हो या यदि यह आपका कोड हो। इसका मतलब है कि आपको फ़ाइल खोलनी होगी और इसे मेमोरी में पढ़ना होगा यदि फाइल बड़ी है तो यह संभावित रूप से एक समस्या है क्योंकि मेमोरी को कचरा एकत्र करने की आवश्यकता है।
नीमा आरा ने एक अच्छा विश्लेषण किया जिसे आप ध्यान में रख सकते हैं
यहां प्रस्तावित समाधान है, क्योंकि यह एक बार में 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;
}
ऊपर आप देख सकते हैं कि एक पंक्ति को एक समय में एक अक्षर के साथ-साथ अंतर्निहित ढांचे द्वारा पढ़ा जाता है क्योंकि आपको पंक्ति फ़ीड देखने के लिए सभी वर्णों को पढ़ने की आवश्यकता है।
यदि आप इसे खाड़ी नीमा के रूप में प्रोफाइल करते हैं, तो आप देखेंगे कि यह ऐसा करने का एक तेज़ और कुशल तरीका है।
एक व्यवहार्य विकल्प, और एक जो मैंने व्यक्तिगत रूप से उपयोग किया है, वह फ़ाइल की पहली पंक्ति में अपने हेडर को जोड़ना होगा। मैंने अपने खेल के लिए एक कस्टम मॉडल प्रारूप के लिए ऐसा किया। असल में, मेरे पास एक उपकरण है जो मेरी .obj फ़ाइलों का अनुकूलन करता है, जिस बकवास की मुझे ज़रूरत नहीं है उससे छुटकारा पाने के लिए, उन्हें एक बेहतर लेआउट में परिवर्तित करता है, और फिर कुल पंक्तियों, चेहरों, मानदंडों, कोने और बनावट UVs पर लिखता है बहुत पहली पंक्ति। मॉडल लोड होने पर विभिन्न डेटा बफ़र्स द्वारा उस डेटा का उपयोग किया जाता है।
यह इसलिए भी उपयोगी है क्योंकि आपको केवल लाइनों को गिनने के लिए एक बार फ़ाइल के माध्यम से लूप की आवश्यकता होती है, एक बार लाइनों को गिनने के लिए, और फिर से आपके बनाए बफ़र्स में डेटा पढ़ने के लिए।
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 एक बाहरी प्रक्रिया के रूप में और स्थापना की आवश्यकता नहीं है) रन। यह विभिन्न लाइन काउंट तरीकों (जैसे यूनिक्स बनाम मैक बनाम विंडोज़) का समर्थन करता है।