উত্তর:
গুরুতরভাবে বেল্ট সম্পাদনা: আপনি। নেট 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++;
}
}
সম্পাদনা: দক্ষতা সম্পর্কে প্রশ্নের জবাবে
দ্বিতীয়টি যেহেতু আমি বেশি দক্ষ বলেছিলাম তা স্মরণে ব্যবহারের বিষয়ে ছিল, অগত্যা গতি নয়। প্রথমটি ফাইলের সম্পূর্ণ সামগ্রী একটি অ্যারেতে লোড করে যার অর্থ এটি অবশ্যই ফাইলের আকার হিসাবে কমপক্ষে মেমরি বরাদ্দ করতে হবে। দ্বিতীয়টি কেবল একবারে একটি লাইন লুপ করে তাই এটি একবারে এক লাইনের বেশি মেমরির বরাদ্দ করতে হয় না। এটি ছোট ফাইলগুলির পক্ষে তেমন গুরুত্বপূর্ণ নয়, তবে বড় ফাইলগুলির জন্য এটি একটি সমস্যা হতে পারে (আপনি যদি চেষ্টা করে 32b-বিট সিস্টেমে 4GB ফাইলে লাইন সংখ্যাটি খুঁজে বের করেন, উদাহরণস্বরূপ, যেখানে কেবল পর্যাপ্ত পরিমাণ নেই) ব্যবহারকারী-মোড ঠিকানার স্থানটি এটিকে বড় পরিমাণে বরাদ্দ করতে)।
গতির দিক দিয়ে আমি এতে অনেক কিছু হওয়ার আশা করবো না। এটি সম্ভব যে রিডএললাইনগুলির কিছু অভ্যন্তরীণ অপ্টিমাইজেশন রয়েছে তবে অন্যদিকে এটি মেমরির একটি বিশাল অংশ বরাদ্দ করতে হতে পারে। আমি অনুমান করতে পারি যে রিডআললাইনগুলি ছোট ফাইলগুলির জন্য দ্রুত হতে পারে তবে বড় ফাইলগুলির জন্য উল্লেখযোগ্যভাবে ধীর গতিতে; যদিও বলার একমাত্র উপায় হ'ল এটি একটি স্টপওয়াচ বা কোড প্রোফাইলার দিয়ে পরিমাপ করা।
ReadLines().Count()
একটি যুক্ত করতে হবে using System.Linq
। এই সংযোজনটির প্রয়োজন মনে হয়েছে এটি মোটামুটি স্বজ্ঞাত নয়, তাই আমি এটি উল্লেখ করছি mention আপনি যদি ভিজুয়াল স্টুডিও ব্যবহার করছেন তবে সম্ভবত এটি সংযোজন স্বয়ংক্রিয়ভাবে হয়ে গেছে।
যদি সহজেই আপনি বোঝাতে চান কোডের একটি লাইন বোঝা সহজ তবে প্রতি সুযোগে অক্ষম?
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 ফাইলগুলিকে অনুকূল করে, আমার যে ক্র্যাপগুলি দরকার নেই তা থেকে মুক্তি পেয়ে এগুলি একটি ভাল বিন্যাসে রূপান্তরিত করে, এবং তারপরে লাইন, মুখ, নরমালস, শীর্ষগুলি এবং টেক্সচার ইউভিগুলিতে মোট সংখ্যা লিখে যায়। প্রথম লাইন মডেলটি লোড হওয়ার পরে সেই তথ্যটি বিভিন্ন অ্যারে বাফার দ্বারা ব্যবহৃত হয়।
এটিও দরকারী কারণ আপনার ফাইলটি একবারে লোড করার জন্য একবারে লাইনগুলি গণনা করার পরিবর্তে এবং আপনার তৈরি বাফারগুলিতে আবার ডেটা পড়তে হবে।
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 একটি বহিস্থিত প্রক্রিয়া হিসেবে এবং ইনস্টলেশন প্রয়োজন নেই) রান। এটি বিভিন্ন লাইন গণনা পদ্ধতি সমর্থন করে (যেমন ইউনিক্স বনাম ম্যাক বনাম উইন্ডো))