সি # তে স্ট্রিম সহ বড় টেক্সট ফাইলগুলি পড়া


97

আমাদের অ্যাপ্লিকেশনটির স্ক্রিপ্ট সম্পাদক (বড় ম্যাক্রোগুলির জন্য আমাদের অভ্যন্তরীণ পণ্যের জন্য এটি ভিবিএর মতো ) কীভাবে বড় ফাইলগুলি পরিচালনা করা যায় তা পরিচালনা করার জন্য আমি সুন্দর কাজ পেয়েছি । বেশিরভাগ ফাইলগুলি প্রায় 300-400 কেবি যা জরিমানা লোড হয়। কিন্তু যখন তারা 100 এমবি ছাড়িয়ে যায় তখন প্রক্রিয়াটিতে একটি কঠিন সময় (যেমনটি আপনি আশা করেছিলেন) করতে হবে।

যা ঘটে তা হ'ল ফাইলটি রিচটেক্সটবক্সে পড়ে এবং নেভিগেট করা হয় - এই অংশটি সম্পর্কে খুব বেশি চিন্তা করবেন না।

যে বিকাশকারী প্রাথমিক কোডটি লিখেছেন তারা কেবল স্ট্রিমরিডার ব্যবহার করে এবং করছেন

[Reader].ReadToEnd()

যা সম্পূর্ণ হতে বেশ কিছুটা সময় নিতে পারে।

আমার কাজটি হ'ল এই বিট কোডটি ভাঙা, খণ্ডগুলিতে এটি একটি বাফারে পড়ুন এবং এটি বাতিল করার বিকল্প সহ একটি প্রগতি বার দেখান।

কিছু অনুমান:

  • বেশিরভাগ ফাইল 30-40 এমবি হবে
  • ফাইলটির বিষয়বস্তু হ'ল পাঠ্য (বাইনারি নয়), কিছু ইউনিক্স ফর্ম্যাট, কিছু ডস।
  • বিষয়বস্তুগুলি পুনরুদ্ধার করা হলে আমরা কী টার্মিনেটর ব্যবহার করা হয় তা নিয়ে কাজ করি।
  • রিচটেক্সটবক্সে রেন্ডার করতে সময়টি লোড হওয়ার পরে কারওই উদ্বেগ নেই। এটি কেবল পাঠ্যের প্রাথমিক লোড।

এখন প্রশ্নের জন্য:

  • আমি কি কেবল স্ট্রিমরিডার ব্যবহার করতে পারি, তারপরে দৈর্ঘ্যের সম্পত্তিটি পরীক্ষা করতে পারি (সুতরাং প্রগ্রেসম্যাক্স) এবং একটি সেট বাফার আকারের জন্য একটি রিড জারি করতে পারি এবং কিছুক্ষণের মধ্যে পুনরুক্তি করতে পারা যায় কোনও ব্যাকগ্রাউন্ড কর্মীর ভিতরে থাকা অবস্থায় , সুতরাং এটি মূল ইউআই থ্রেডটি ব্লক করে না? তারপরে স্ট্রিংবিল্ডারটি সম্পূর্ণ হয়ে গেলে মূল থ্রেডে ফিরিয়ে দিন।
  • সামগ্রীগুলি একটি স্ট্রিংবিল্ডারে যাবে। দৈর্ঘ্য উপলব্ধ থাকলে আমি স্ট্রিংবিল্ডার স্ট্রিমের আকার দিয়ে আরম্ভ করতে পারি?

এগুলি কি (আপনার পেশাদার মতামতে) ভাল ধারণা? স্ট্রিমস থেকে কন্টেন্ট পড়ার আগে আমার কয়েকটি সমস্যা ছিল, কারণ এটি সর্বদা সর্বশেষ কয়েকটি বাইট বা কিছু মিস করবে তবে আমি অন্য প্রশ্ন জিজ্ঞাসা করব যদি এই ঘটনাটি হয় তবে।


29
30-40MB স্ক্রিপ্ট ফাইল? পবিত্র ম্যাকেরেল! আমি কোড পর্যালোচনা করতে পছন্দ করি না ...
dthorpe

আমি জানি এই প্রশ্নগুলি বরং পুরানো তবে আমি অন্য দিন এটি পেয়েছি এবং মেমোরিপ্যাডফাইলে প্রস্তাবনাটি পরীক্ষা করেছি এবং এটি দ্রুততম পদ্ধতির হাতছাড়া। একটি তুলনা পড়তে পঠন পদ্ধতির মাধ্যমে একটি 7,616,939 লাইন 345MB ফাইলটি পড়ছে একই মেশিনটি সম্পাদন করার সময় আমার মেশিনে 12+ ঘন্টা সময় লাগে এবং মেমরিমেপডফাইলে পড়তে 3 সেকেন্ড সময় নেয়।
সিসনন

এটি কোডের কয়েকটি লাইন। এই গ্রন্থাগারটি দেখুন আমি 25 জিবি এবং আরও বড় ফাইলগুলি পড়তে ব্যবহার করছি। github.com/Agenty/FileReader
বিকাশ

উত্তর:


177

আপনি এর মতো একটি বাফার্ড স্ট্রিম ব্যবহার করে পড়ার গতি উন্নত করতে পারেন:

using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs))
{
    string line;
    while ((line = sr.ReadLine()) != null)
    {

    }
}

মার্চ 2013 আপডেট

আমি সম্প্রতি পঠন এবং প্রক্রিয়াকরণের জন্য কোড লিখেছি (পাঠ্যের জন্য সন্ধান করা) 1 জিবি-ইশ পাঠ্য ফাইল (এখানে জড়িত ফাইলগুলির চেয়ে অনেক বড়) এবং প্রযোজক / ভোক্তা নিদর্শন ব্যবহার করে একটি উল্লেখযোগ্য পারফরম্যান্স লাভ অর্জন করেছি। প্রযোজক টাস্কটি পাঠ্যের লাইনে পড়েন BufferedStreamএবং সেগুলি একটি পৃথক গ্রাহক কার্যের হাতে তুলে দেন যা অনুসন্ধান করে did

আমি এটি টিপিএল ডেটাফ্লো শেখার সুযোগ হিসাবে ব্যবহার করেছি, যা এই প্যাটার্নটি দ্রুত কোডিংয়ের জন্য খুব উপযুক্ত।

বাফারড্রিম কেন দ্রুত

একটি বাফার ডেটা ক্যাশে করতে ব্যবহৃত মেমোরিতে থাকা বাইটগুলির একটি ব্লক, যার ফলে অপারেটিং সিস্টেমে কলগুলির সংখ্যা হ্রাস পায়। বাফারগুলি পড়ার এবং লেখার কর্মক্ষমতা উন্নত করে। একটি বাফার হয় পড়া বা লেখার জন্য ব্যবহার করা যেতে পারে, তবে উভয়ই একই সাথে নয়। বাফারড স্ট্রিমের পড়ুন এবং লেখার পদ্ধতিগুলি স্বয়ংক্রিয়ভাবে বাফারকে বজায় রাখে।

ডিসেম্বর 2014 আপডেট: আপনার মাইল পরিবর্তন হতে পারে

মন্তব্য উপর ভিত্তি করে, FileStream একটি ব্যবহার করা উচিত BufferedStream অভ্যন্তরীণভাবে। এই উত্তরটি প্রথম সরবরাহ করার সময়, আমি একটি বাফারডস্ট্রিম যুক্ত করে একটি উল্লেখযোগ্য পারফরম্যান্স বাস্ট পরিমাপ করেছি। এই সময় আমি 32-বিট প্ল্যাটফর্মে .NET 3.x টার্গেট করছিলাম। আজ, 64-বিট প্ল্যাটফর্মে .NET 4.5 টার্গেট করে আমি কোনও উন্নতি দেখতে পাচ্ছি না।

সম্পর্কিত

আমি এমন একটি ক্ষেত্রে এসে পৌঁছলাম যেখানে একটি এএসপি থেকে নেট, জেনারেট স্ট্রিমে জেনারেট হওয়া CSV ফাইলটি স্ট্রিমিং হয়ে গেছে et নেট এমভিসি ক্রিয়াটি খুব ধীর ছিল। একটি উদাহরণস্বরূপ 100x দ্বারা উন্নত পারফরম্যান্সে একটি বাফারড্রিম যুক্ত করা আরও তথ্যের জন্য Unbuffered আউটপুট খুব ধীর দেখুন


12
ডুড, বাফারডস্ট্রিম সমস্ত পার্থক্য করে। +1 :)
মার্কাস

4
আইও সাবসিস্টেম থেকে ডেটা অনুরোধ করার জন্য একটি খরচ আছে। ঘূর্ণনশীল ডিস্কগুলির ক্ষেত্রে, আপনাকে পরবর্তী পর্বের ডেটা পড়ার জন্য প্লেটারটি স্পিনে অবস্থানের জন্য অপেক্ষা করতে হতে পারে বা আরও খারাপ, ডিস্কের মাথাটি সরে যাওয়ার জন্য অপেক্ষা করুন। এসএসডি-তে জিনিসগুলি ধীর করার জন্য যান্ত্রিক অংশ নেই, তবুও তাদের অ্যাক্সেস করার জন্য প্রতি-আইও-অপারেশন ব্যয় রয়েছে। বাফার স্ট্রিমগুলি ওএসে কল করার সংখ্যা হ্রাস করে এবং শেষ পর্যন্ত পৃথক আইও অনুরোধের সংখ্যাকে হ্রাস করে স্ট্রিমরিডার যা অনুরোধ করে তার চেয়েও বেশি বেশি পড়তে পারে।
এরিক জে।

4
সত্যি? এটি আমার পরীক্ষার দৃশ্যে কোনও পার্থক্য করে না। ব্র্যাড আব্রামের মতে কোনও ফাইল স্ট্রিমের উপরে বাফারড্রিম ব্যবহার করার কোনও সুবিধা নেই।
নিক কক্স

4
@ নিককক্স: আপনার ফলাফলগুলি আপনার অন্তর্নিহিত আইও সাবসিস্টেমের ভিত্তিতে পরিবর্তিত হতে পারে। একটি ঘূর্ণনশীল ডিস্ক এবং একটি ডিস্ক নিয়ামক যার ক্যাশে ডেটা নেই (এবং উইন্ডোজ দ্বারা ডেটা ক্যাশে করা হয় না) তেও স্পিডআপ বিশাল। ব্র্যাডের কলামটি 2004 সালে রচিত হয়েছিল I
এরিক জে।

4
এই অনুযায়ী অনর্থক: stackoverflow.com/questions/492283/... FileStream ইতিমধ্যে একটি বাফার অভ্যন্তরীণভাবে ব্যবহার করে।
এরউইন মায়ার

22

আপনি পড়তে পারেন এই ওয়েবসাইটে কর্মক্ষমতা এবং বেঞ্চমার্ক পরিসংখ্যান , আপনি দেখতে পাবেন যে দ্রুততর উপায় হল থেকে পড়া (কারণ পড়া, লেখা, এবং প্রক্রিয়াকরণ হয় সব বিভিন্ন) একটি টেক্সট ফাইল কোডের নিম্নলিখিত স্নিপেট হল:

using (StreamReader sr = File.OpenText(fileName))
{
    string s = String.Empty;
    while ((s = sr.ReadLine()) != null)
    {
        //do your stuff here
    }
}

প্রায় 9 টি বিভিন্ন পদ্ধতির বেঞ্চ চিহ্নিত করা হয়েছিল, তবে এটি মনে হয় যে বেশিরভাগ সময় সামনে আসে, এমনকি অন্য পাঠকরা যেমন উল্লেখ করেছেন তেমনি বাফার রিডারও সম্পাদন করে চলেছে


4
এটি একাধিক ফাইলে স্কুয়েল সিনট্যাক্সে অনুবাদ করার জন্য একটি 19 গিগাবাইট পোস্টগ্রিজ ফাইল আলাদা করার জন্য ভাল কাজ করেছে। ধন্যবাদ পোস্টগ্রিজ লোক যিনি কখনই আমার পরামিতিগুলি সঠিকভাবে কার্যকর করেননি। / দীর্ঘশ্বাস
ড্যামন ড্রাক

এখানে পারফরম্যান্সের পার্থক্যটি সত্যই বড় ফাইলগুলির জন্য পরিশোধ করতে হবে বলে মনে হচ্ছে, যেমন 150MB এর চেয়েও বড় (আপনার মেমরিগুলিতে StringBuilderলোড করার জন্য আপনার সত্যিই একটি ব্যবহার করা উচিত , যত দ্রুত আপনি চার্জ যুক্ত করার সময় এটি নতুন স্ট্রিং তৈরি করে না তাই দ্রুত লোড হয়)
জোশুয়া জি

15

আপনি বলছেন যে একটি বড় ফাইল লোড হওয়ার সময় আপনাকে একটি অগ্রগতি বার দেখাতে বলা হয়েছিল। এর কারণ কি ব্যবহারকারীরা প্রকৃতপক্ষে ফাইল লোডিংয়ের সঠিক %টি দেখতে চান, বা কেবল যে কারণে কিছু ঘটছে তার ভিজ্যুয়াল প্রতিক্রিয়া চান?

যদি দ্বিতীয়টি সত্য হয় তবে সমাধানটি আরও সহজ হয়ে যায়। কেবল reader.ReadToEnd()একটি পটভূমির থ্রেডে করুন, এবং উপযুক্তের পরিবর্তে একটি মার্কি-প্রকারের অগ্রগতি বারটি প্রদর্শন করুন।

আমি এই বিষয়টি উত্থাপন করি কারণ আমার অভিজ্ঞতায় এটি প্রায়শই ঘটে। আপনি যখন একটি ডেটা প্রসেসিং প্রোগ্রাম লিখছেন, তখন ব্যবহারকারীরা অবশ্যই একটি% সম্পূর্ণ চিত্রের প্রতি আগ্রহী হয়ে উঠবে, তবে সাধারণ-ধীর-ধীর ইউআই আপডেটের জন্য, তারা কেবল এটি জানতে পারে যে কম্পিউটারটি ক্রাশ হয়নি। :-)


4
কিন্তু ব্যবহারকারী কি রিডটোএন্ড কলটি বাতিল করতে পারে?
টিম স্কার্বারো

@ টিম, ভাল দাগযুক্ত। যে ক্ষেত্রে, আমরা ফিরে যেতে বসেছেন StreamReaderলুপ। তবে এটি এখনও সহজ হবে কারণ অগ্রগতি সূচক গণনা করার জন্য সামনে পড়ার দরকার নেই।
খ্রিস্টান হাইটার

8

বাইনারি ফাইলগুলির জন্য, আমি তাদের খুঁজে পাওয়ার দ্রুততম উপায়টি এটি।

 MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(file);
 MemoryMappedViewStream mms = mmf.CreateViewStream();
 using (BinaryReader b = new BinaryReader(mms))
 {
 }

আমার পরীক্ষায় এটি কয়েকগুণ দ্রুত।


4
আপনার কাছে এর কোনও শক্ত প্রমাণ আছে? অন্য কোনও উত্তরের জন্য কেন ওপিকে এটি ব্যবহার করা উচিত? দয়া করে কিছুটা গভীর খনন করুন এবং আরও কিছু বিশদ দিন
ডিলান কোরিভাউ

7

একটি পটভূমি কর্মী ব্যবহার করুন এবং কেবল সীমিত সংখ্যক লাইন পড়ুন। ব্যবহারকারী যখন স্ক্রোল করবেন তখনই আরও পড়ুন।

এবং কখনও রিডটোএন্ড () ব্যবহার করার চেষ্টা করবেন না। এটি এমন একটি ফাংশন যা আপনি ভাবেন যে "তারা এগুলি কেন তৈরি করেছিল?"; এটি একটি স্ক্রিপ্ট বাচ্চাদের সহায়তাকারী যা ছোট ছোট জিনিসগুলির সাথে সূক্ষ্ম হয়, তবে আপনি যেমন দেখেন যে এটি বড় ফাইলগুলির জন্য ব্যর্থ হয় ...

আপনারা স্ট্রিংবিল্ডার ব্যবহার করতে বলছেন এমন লোকদের আরও প্রায়শই এমএসডিএন পড়তে হবে:

পারফরমেন্স বিবেচ্য বিষয়
একটি বিদ্যমান স্ট্রিং বা StringBuilder বস্তু CONCAT এবং AppendFormat পদ্ধতি উভয় CONCATENATE নতুন তথ্য। একটি স্ট্রিং অবজেক্ট কনটেনটেশন অপারেশন সর্বদা বিদ্যমান স্ট্রিং এবং নতুন ডেটা থেকে একটি নতুন অবজেক্ট তৈরি করে। একটি স্ট্রিংবিল্ডার অবজেক্ট নতুন ডেটার সংমিশ্রণকে সামঞ্জস্য করার জন্য একটি বাফার পরিচালনা করে। ঘর উপলব্ধ থাকলে বাফার শেষে নতুন ডেটা যুক্ত করা হবে; অন্যথায়, একটি নতুন, বৃহত্তর বাফার বরাদ্দ করা হয়, মূল বাফার থেকে ডেটা নতুন বাফারে অনুলিপি করা হয়, তারপরে নতুন ডেটা নতুন বাফারে যুক্ত করা হয়। কোনও স্ট্রিং বা স্ট্রিংবিল্ডার অবজেক্টের জন্য একটি কনটেশনেশন অপারেশনের কর্মক্ষমতা মেমরির বরাদ্দ কতবার ঘটে তার উপর নির্ভর করে।
একটি স্ট্রিং কনটেনটেশন অপারেশন সর্বদা মেমরি বরাদ্দ করে, অন্যদিকে স্ট্রিংবিল্ডার অবজেক্ট বাফার নতুন ডেটা সামঞ্জস্য করতে খুব কম হলে স্ট্রিংবিল্ডার কনটেনটেশন অপারেশন কেবল মেমরি বরাদ্দ করে। ফলস্বরূপ, স্ট্রিং ক্লাস একটি সংক্ষিপ্ত ক্রিয়াকলাপের জন্য পছন্দসই হয় যদি একটি নির্দিষ্ট সংখ্যক স্ট্রিং অবজেক্টকে সংযুক্ত করা হয়। সেক্ষেত্রে পৃথক কনটেনটেশন অপারেশনগুলি এমনকি সংকলক দ্বারা একটি একক ক্রিয়াকলাপের সাথে সংযুক্ত করা যেতে পারে। একটি স্ট্রিংবিল্ডার অবজেক্ট কনটেনটেশন অপারেশনের জন্য পছন্দনীয় যদি একটি স্বেচ্ছামূলক সংখ্যক স্ট্রিং সংমিশ্রিত হয়; উদাহরণস্বরূপ, যদি কোনও লুপ ব্যবহারকারীর ইনপুটটির এলোমেলো সংখ্যক স্ট্রিংকে সম্মতি দেয়।

এর অর্থ মেমরির বিশাল বরাদ্দ, যা সোয়াপ ফাইল সিস্টেমের বৃহত ব্যবহারে পরিণত হয়, যা আপনার হার্ড ডিস্ক ড্রাইভের বিভাগগুলিকে র‌্যাম মেমরির মতো কাজ করতে সিমুলেট করে, তবে একটি হার্ড ডিস্ক ড্রাইভ খুব ধীর হয়।

কারা মনো-ব্যবহারকারী হিসাবে সিস্টেমটি ব্যবহার করে তার জন্য স্ট্রিংবিল্ডার বিকল্পটি দুর্দান্ত দেখায়, তবে আপনার যখন একই সাথে দুটি বা ততোধিক ব্যবহারকারী বড় ফাইল পড়েন তখন আপনার সমস্যা হয়।


আপনি ছেলেরা খুব দ্রুত! দুর্ভাগ্যক্রমে কারণ যেভাবে ম্যাক্রোর কাজ করে পুরো স্ট্রিমটি লোড করা দরকার। যেমনটি আমি উল্লেখ করেছি সমৃদ্ধ অংশটি নিয়ে চিন্তা করবেন না। এটির প্রাথমিক লোডিংটি আমরা উন্নতি করতে চাই।
নিকোল লি

যাতে আপনি অংশে কাজ করতে পারেন, প্রথম এক্স লাইনগুলি পড়তে পারেন, ম্যাক্রো প্রয়োগ করতে পারেন, দ্বিতীয় এক্স লাইনগুলি পড়তে পারেন, ম্যাক্রো প্রয়োগ করতে পারেন, এবং আরও অনেক কিছু ... আপনি যদি এই ম্যাক্রোটি করেন তা ব্যাখ্যা করে, আমরা আপনাকে আরও নির্ভুলতার সাথে সহায়তা করতে পারি
টুফো

5

আপনার শুরু করার জন্য এটি যথেষ্ট হবে।

class Program
{        
    static void Main(String[] args)
    {
        const int bufferSize = 1024;

        var sb = new StringBuilder();
        var buffer = new Char[bufferSize];
        var length = 0L;
        var totalRead = 0L;
        var count = bufferSize; 

        using (var sr = new StreamReader(@"C:\Temp\file.txt"))
        {
            length = sr.BaseStream.Length;               
            while (count > 0)
            {                    
                count = sr.Read(buffer, 0, bufferSize);
                sb.Append(buffer, 0, count);
                totalRead += count;
            }                
        }

        Console.ReadKey();
    }
}

4
আমি "var বাফার = নতুন চর [1024]" লুপের বাইরে সরিয়ে নিয়ে যাব: প্রতিবার নতুন বাফার তৈরি করা প্রয়োজন হবে না। এটি কেবল "যখন (গণনা> 0)" এর আগে রাখুন।
টমি কার্লিয়ার

4

নিম্নলিখিত কোড স্নিপেট এক নজরে দেখুন। আপনি উল্লেখ করেছেন Most files will be 30-40 MB। এটি একটি ইন্টেল কোয়াড কোরে ১.৪ সেকেন্ডে 180 এমবি পড়ার দাবি করে:

private int _bufferSize = 16384;

private void ReadFile(string filename)
{
    StringBuilder stringBuilder = new StringBuilder();
    FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);

    using (StreamReader streamReader = new StreamReader(fileStream))
    {
        char[] fileContents = new char[_bufferSize];
        int charsRead = streamReader.Read(fileContents, 0, _bufferSize);

        // Can't do much with 0 bytes
        if (charsRead == 0)
            throw new Exception("File is 0 bytes");

        while (charsRead > 0)
        {
            stringBuilder.Append(fileContents);
            charsRead = streamReader.Read(fileContents, 0, _bufferSize);
        }
    }
}

মূল নিবন্ধ


4
এই ধরণের পরীক্ষাগুলি কুখ্যাতভাবে বিশ্বাসযোগ্য নয়। আপনি পরীক্ষার পুনরাবৃত্তি করার সময় আপনি ফাইল সিস্টেম ক্যাশে থেকে ডেটা পড়বেন। এটি একটি বাস্তব পরীক্ষার চেয়ে কমপক্ষে একটি মাত্রার গতিবেগ যা ডিস্কের বাইরে থাকা ডেটা পড়ে। একটি 180 এমবি ফাইল সম্ভবত 3 সেকেন্ডেরও কম সময় নিতে পারে না। আপনার মেশিনটি পুনরায় বুট করুন, আসল সংখ্যার জন্য একবার পরীক্ষা চালান।
হ্যানস প্যাস্যান্ট

7
লাইন স্ট্রিংবিল্ডার.অ্যাপেন্ডটি সম্ভাব্য বিপজ্জনক, আপনার স্ট্রিংবিল্ডার.অ্যাপেন্ড (ফাইলকন্টেন্টস, 0, চার্স রিড) দিয়ে এটি প্রতিস্থাপন করতে হবে; স্ট্রিমটি ইতিমধ্যে শেষ হয়ে গেলেও আপনি পুরো 1024 টি চর যোগ করছেন না তা নিশ্চিত করতে।
জোহানেস রুডলফ

@ জোহনেস রুডল্ফ, আপনার মন্তব্যটি আমাকে একটি বাগ সমাধান করেছে। আপনি কীভাবে 1024 নম্বর নিয়ে এসেছেন?
অফিরিড

3

আপনি এখানে হ্যান্ডলিং করে মেমরি-ম্যাপযুক্ত ফাইলগুলি ব্যবহার করা ভাল .. / একই কাজ করতে অনুরোধ ..

সম্পাদনা করুন: এটি কীভাবে কাজ করে তার জন্য এখানে এমএসডিএন দেখুন , আসন্ন। নেট 4 এ এটি কীভাবে করা হয় তা নির্দেশ করে এখানে ব্লগ এন্ট্রি রয়েছে। এর আগে আমি যে লিঙ্কটি দিয়েছি তা হ'ল এটি অর্জনের জন্য পিনভোকের চারপাশে একটি মোড়ক। আপনি পুরো ফাইলটিকে মেমরিতে ম্যাপ করতে পারেন এবং ফাইলের মাধ্যমে স্ক্রোল করার সময় এটিকে স্লাইডিং উইন্ডোর মতো দেখতে পারেন।


3

সব চমৎকার উত্তর! তবে, কারও উত্তর সন্ধান করার জন্য এগুলি কিছুটা অসম্পূর্ণ বলে মনে হচ্ছে।

আপনার কনফিগারেশনের উপর নির্ভর করে স্ট্যান্ডার্ড স্ট্রিং কেবল আকার এক্স, 2 জিবি থেকে 4 জিবি করতে পারে, এই উত্তরগুলি ওপির প্রশ্নটি সত্যিই পূরণ করে না। একটি পদ্ধতি স্ট্রিংয়ের তালিকার সাথে কাজ করা:

List<string> Words = new List<string>();

using (StreamReader sr = new StreamReader(@"C:\Temp\file.txt"))
{

string line = string.Empty;

while ((line = sr.ReadLine()) != null)
{
    Words.Add(line);
}
}

কিছু প্রক্রিয়াজাতকরণের সময় টোকেনাইজ করতে এবং লাইনটি বিভক্ত করতে পারে। স্ট্রিং তালিকায় এখন পাঠ্যের খুব বড় পরিমাণ রয়েছে।


1

কোনও পুনরুক্তিকারী এই ধরণের কাজের জন্য উপযুক্ত হতে পারে:

public static IEnumerable<int> LoadFileWithProgress(string filename, StringBuilder stringData)
{
    const int charBufferSize = 4096;
    using (FileStream fs = File.OpenRead(filename))
    {
        using (BinaryReader br = new BinaryReader(fs))
        {
            long length = fs.Length;
            int numberOfChunks = Convert.ToInt32((length / charBufferSize)) + 1;
            double iter = 100 / Convert.ToDouble(numberOfChunks);
            double currentIter = 0;
            yield return Convert.ToInt32(currentIter);
            while (true)
            {
                char[] buffer = br.ReadChars(charBufferSize);
                if (buffer.Length == 0) break;
                stringData.Append(buffer);
                currentIter += iter;
                yield return Convert.ToInt32(currentIter);
            }
        }
    }
}

আপনি নিম্নলিখিতটি ব্যবহার করে এটি কল করতে পারেন:

string filename = "C:\\myfile.txt";
StringBuilder sb = new StringBuilder();
foreach (int progress in LoadFileWithProgress(filename, sb))
{
    // Update your progress counter here!
}
string fileData = sb.ToString();

ফাইলটি লোড হওয়ার সাথে সাথে পুনরাবৃত্তিটি 0 থেকে 100 পর্যন্ত অগ্রগতি নম্বরটি ফিরিয়ে দেবে, যা আপনি আপনার অগ্রগতি বার আপডেট করতে ব্যবহার করতে পারেন। লুপটি শেষ হয়ে গেলে, স্ট্রিংবিল্ডারটিতে পাঠ্য ফাইলের বিষয়বস্তু থাকবে।

এছাড়াও, আপনি পাঠ্য চান বলে, আমরা কেবল অক্ষরগুলিতে পড়ার জন্য বাইনারিআডার ব্যবহার করতে পারি, এটি নিশ্চিত করবে যে কোনও মাল্টি-বাইট অক্ষর ( ইউটিএফ -8 , ইউটিএফ -16 ইত্যাদি) পড়ার সময় আপনার বাফারগুলি সঠিকভাবে লাইন রেখেছে ।

ব্যাকগ্রাউন্ড টাস্ক, থ্রেড বা জটিল কাস্টম স্টেট মেশিন ব্যবহার না করেই এটি করা হয়।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.