C # में स्ट्रीम के साथ बड़ी टेक्स्ट फाइल पढ़ना


96

मुझे अपने एप्लिकेशन के स्क्रिप्ट एडिटर में लोड की जा रही बड़ी फ़ाइलों को संभालने का सुंदर काम मिला है (यह VBA की तरह है त्वरित मैक्रोज़ के लिए हमारे आंतरिक उत्पाद के लिए )। अधिकांश फाइलें लगभग 300-400 केबी की होती हैं जो ठीक लोड होती हैं। लेकिन जब वे 100 एमबी से आगे जाते हैं तो प्रक्रिया में एक कठिन समय होता है (जैसा कि आप उम्मीद करेंगे)।

क्या होता है कि फ़ाइल पढ़ी जाती है और एक रिचटॉक्सबॉक्स में भेज दी जाती है, जिसे तब नेविगेट किया जाता है - इस हिस्से के बारे में बहुत चिंता न करें।

डेवलपर जिसने प्रारंभिक कोड लिखा है, वह केवल स्ट्रीमरडर और कर का उपयोग कर रहा है

[Reader].ReadToEnd()

जिसे पूरा होने में काफी समय लग सकता है।

मेरा काम कोड के इस बिट को तोड़ना है, इसे एक बफर में चंक्स में पढ़ें और इसे रद्द करने के विकल्प के साथ एक प्रगति पट्टी दिखाएं।

कुछ धारणाएँ:

  • ज्यादातर फाइलें 30-40 एमबी की होंगी
  • फ़ाइल की सामग्री पाठ है (बाइनरी नहीं), कुछ यूनिक्स प्रारूप हैं, कुछ डॉस हैं।
  • एक बार सामग्री पुनर्प्राप्त हो जाने के बाद हम बाहर काम करते हैं कि क्या टर्मिनेटर का उपयोग किया जाता है।
  • रिचटेक्स्टबॉक्स में रेंडर करने में लगने वाले समय को लोड करने के बाद किसी का भी संबंध नहीं है। यह केवल पाठ का प्रारंभिक भार है।

अब प्रश्नों के लिए:

  • क्या मैं केवल स्ट्रीमराइडर का उपयोग कर सकता हूं, फिर लंबाई की संपत्ति (तो प्रोग्रेसमैक्स) की जांच कर सकता हूं और एक सेट बफर साइज के लिए रीड जारी कर सकता हूं और एक बैकग्राउंड वर्कर के अंदर थोड़ी देर के लूप व्हाट्सएप के माध्यम से पुनरावृति कर सकता हूं , इसलिए यह मुख्य यूआई थ्रेड को ब्लॉक नहीं करता है? फिर पूरा होने पर स्ट्रिंगर को मुख्य धागे में लौटा दें।
  • सामग्री StringBuilder में जा रही होगी। अगर लंबाई उपलब्ध है तो क्या मैं स्ट्रिंग के आकार के साथ स्ट्रिंगबर्ल को इनिशियलाइज़ कर सकता हूँ?

क्या ये (आपके पेशेवर विचारों में) अच्छे विचार हैं? मैं स्ट्रीम से सामग्री पढ़ने के साथ अतीत में कुछ मुद्दों पर था, क्योंकि यह हमेशा पिछले कुछ बाइट्स या कुछ और याद होगा, लेकिन अगर यह मामला है तो मैं एक और सवाल पूछूंगा।


29
30-40MB स्क्रिप्ट फ़ाइलें? पवित्र मैकेरल! मुझे कोड की समीक्षा करने से नफरत होगी ...
dthorpe

मुझे पता है कि यह प्रश्न पुराना है, लेकिन मैंने इसे दूसरे दिन पाया और मेमोरीमेडफाइल के लिए सिफारिश का परीक्षण किया है और यह सबसे तेज़ तरीका है। एक तुलना एक 7,616,939 लाइन 345MB फ़ाइल को रीडलाइन विधि के माध्यम से पढ़ रहा है, मेरी मशीन पर एक ही लोड करते समय 12+ घंटे लगते हैं और MemoryMappedFile के माध्यम से पढ़ने में 3 सेकंड लगते हैं।
csonon

यह कोड की कुछ पंक्तियाँ हैं। इस लाइब्रेरी को देखें मैं 25gb और अधिक बड़ी फ़ाइलों को पढ़ने के लिए उपयोग कर रहा हूं। github.com/Agenty/FileReader
विकाश राते 3

जवाबों:


175

आप इस तरह से एक बफ़रड्रीम का उपयोग करके रीड स्पीड में सुधार कर सकते हैं:

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और खोज करने वाले एक अलग उपभोक्ता कार्य को उन्हें सौंप देता है।

मैंने इसे TPL डेटाफ़्लो सीखने के अवसर के रूप में उपयोग किया, जो इस पैटर्न को जल्दी से कोड करने के लिए बहुत अच्छी तरह से अनुकूल है।

क्यों बफर्डस्ट्रीम तेज है

एक बफर डेटा को कैश करने के लिए उपयोग की जाने वाली मेमोरी में बाइट्स का एक ब्लॉक है, जिससे ऑपरेटिंग सिस्टम पर कॉल की संख्या कम हो जाती है। बफ़र पढ़ने और प्रदर्शन को बेहतर बनाते हैं। एक बफर का उपयोग या तो पढ़ने या लिखने के लिए किया जा सकता है, लेकिन कभी भी दोनों एक साथ नहीं। बफ़रस्ट्रीम के पढ़ने और लिखने के तरीके स्वचालित रूप से बफर को बनाए रखते हैं।

दिसंबर 2014 अपडेट: आपका माइलेज मई वैरी

टिप्पणियों के आधार पर, फाइलस्ट्रीम का उपयोग किया जाना चाहिए आंतरिक रूप से बफ़रड्रीम । जिस समय यह उत्तर पहली बार दिया गया था, मैंने एक बफ़रडस्ट्रीम जोड़कर एक महत्वपूर्ण प्रदर्शन को बढ़ावा दिया। जब मैं 32-बिट प्लेटफ़ॉर्म पर .NET 3.x को लक्षित कर रहा था। आज, 64-बिट प्लेटफॉर्म पर .NET 4.5 को लक्षित करते हुए, मुझे कोई सुधार नहीं दिखता है।

सम्बंधित

मुझे एक ऐसा मामला सामने आया जहां एक ASP.Net MVC एक्शन से रिस्पॉन्स स्ट्रीम के लिए एक बड़ी, जेनरेट की गई CSV फ़ाइल को स्ट्रीम करना बहुत धीमा था। इस उदाहरण में बफ़रडस्ट्रीम में 100x तक बेहतर प्रदर्शन को जोड़ना। अधिक देखने के लिए Unbuffered आउटपुट बहुत धीमा है


12
यार, बफर्डस्ट्रीम से सारा फर्क पड़ता है। +1 :)
मार्कस

2
एक IO सबसिस्टम से डेटा का अनुरोध करने की लागत है। घूर्णन डिस्क के मामले में, आपको डेटा के अगले भाग को पढ़ने के लिए स्थिति में स्पिन करने के लिए प्लैटर के लिए इंतजार करना पड़ सकता है, या इससे भी बदतर, डिस्क सिर को स्थानांतरित करने के लिए इंतजार करना होगा। हालांकि एसएसडी के पास चीजों को धीमा करने के लिए यांत्रिक भाग नहीं हैं, फिर भी उन्हें एक्सेस करने के लिए प्रति-आईओ-ऑपरेशन लागत है। बफ़र किए गए स्ट्रीम, स्ट्रीमराइडर अनुरोधों की तुलना में अधिक पढ़ते हैं, ओएस पर कॉल की संख्या को कम करते हैं और अंततः अलग-अलग ओओ अनुरोधों की संख्या को कम करते हैं।
एरिक जे।

4
वास्तव में? इससे मेरे परीक्षा परिदृश्य पर कोई फर्क नहीं पड़ता। ब्रैड अब्राम्स के अनुसार, फाइलस्ट्रीम पर बफ़रस्ट्रीम का उपयोग करने का कोई लाभ नहीं है।
निक कॉक्स

2
@ न्यूकॉक्स: आपके परिणाम आपके अंतर्निहित IO सबसिस्टम के आधार पर भिन्न हो सकते हैं। एक घूर्णन डिस्क और एक डिस्क नियंत्रक पर जिसके कैश में डेटा नहीं है (और विंडोज द्वारा कैश नहीं किया गया डेटा भी), स्पीडअप बहुत बड़ा है। ब्रैड का कॉलम 2004 में लिखा गया था। मैंने हाल ही में वास्तविक, कठोर सुधारों को मापा।
एरिक जे।

3
इसके अनुसार यह बेकार है: stackoverflow.com/questions/492283/… फाइलस्ट्रीम पहले से ही आंतरिक रूप से एक बफर का उपयोग करता है।
इरविन मेयर

21

यदि आप इस वेबसाइट पर प्रदर्शन और बेंचमार्क आँकड़े पढ़ते हैं , तो आप देखेंगे कि पढ़ने का सबसे तेज़ तरीका (क्योंकि पढ़ना, लिखना और प्रसंस्करण सभी अलग हैं) एक पाठ फ़ाइल कोड का निम्नलिखित स्निपेट है:

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

सभी 9 अलग-अलग तरीकों को बेंच मार्क किया गया था, लेकिन यह कि अधिकांश समय से आगे निकलते प्रतीत होते हैं, यहां तक ​​कि बफर रीडर का प्रदर्शन भी करते हैं जैसा कि अन्य पाठकों ने उल्लेख किया है।


2
यह एक 19GB पोस्टग्रेज फ़ाइल के अलावा कई फाइलों में sql सिंटैक्स में अनुवाद करने के लिए अलग करने के लिए अच्छी तरह से काम किया। धन्यवाद उस आदमी को बधाई देता हूं जिसने कभी भी मेरे मापदंडों को सही तरीके से निष्पादित नहीं किया। / आह
डेमन ड्रेक

यहां प्रदर्शन अंतर वास्तव में बड़ी फ़ाइलों के लिए भुगतान करने के लिए लगता है, जैसे 150MB से बड़ा (आपको वास्तव StringBuilderमें उन्हें मेमोरी में लोड करने के लिए भी उपयोग करना चाहिए , तेजी से लोड होता है क्योंकि यह हर बार जब आप चार्ट जोड़ते हैं तो नया स्ट्रिंग नहीं बनाते हैं)
यहोशू जी

15

आप कहते हैं कि आपसे एक प्रगति बार दिखाने के लिए कहा गया है जबकि एक बड़ी फ़ाइल लोड हो रही है। क्या इसलिए कि उपयोगकर्ता वास्तव में फ़ाइल लोडिंग का सटीक% देखना चाहते हैं, या सिर्फ इसलिए कि वे दृश्य प्रतिक्रिया चाहते हैं कि कुछ हो रहा है?

यदि उत्तरार्द्ध सच है, तो समाधान बहुत सरल हो जाता है। बस करोreader.ReadToEnd() एक पृष्ठभूमि थ्रेड पर , और एक उचित के बजाय एक मार्की-टाइप प्रगति पट्टी प्रदर्शित करते हैं।

मैं इस बिंदु को बढ़ाता हूं क्योंकि मेरे अनुभव में अक्सर ऐसा होता है। जब आप डेटा प्रोसेसिंग प्रोग्राम लिख रहे होते हैं, तो उपयोगकर्ता निश्चित रूप से% पूर्ण आकृति में रुचि रखते हैं, लेकिन सरल-लेकिन-धीमी यूआई अपडेट के लिए, वे केवल यह जानना चाहते हैं कि कंप्यूटर क्रैश नहीं हुआ है। :-)


2
लेकिन क्या उपयोगकर्ता ReadToEnd कॉल से रद्द कर सकता है?
टिम स्कारबोरो

@ टिम, अच्छी तरह से देखा। उस स्थिति में, हम StreamReaderपाश में वापस आ गए हैं । हालाँकि, यह अभी भी सरल होगा क्योंकि प्रगति संकेतक की गणना करने के लिए आगे पढ़ने की आवश्यकता नहीं है।
क्रिश्चियन हैटर

8

बाइनरी फ़ाइलों के लिए, उन्हें पढ़ने का सबसे तेज़ तरीका मुझे मिला है।

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

मेरे परीक्षणों में यह सैकड़ों गुना तेज है।


2
क्या आपके पास इसका कोई सख्त सबूत है? ओपी को किसी अन्य उत्तर पर इसका उपयोग क्यों करना चाहिए? कृपया थोड़ा गहरा खोदें और थोड़ा और विस्तार दें
डायलन कोरिव्यू

7

एक पृष्ठभूमि कार्यकर्ता का उपयोग करें और केवल सीमित संख्या में लाइनें पढ़ें। उपयोगकर्ता द्वारा स्क्रॉल किए जाने पर ही अधिक पढ़ें।

और ReadToEnd () का कभी उपयोग न करने का प्रयास करें। यह उन कार्यों में से एक है जो आपको लगता है कि "उन्होंने इसे क्यों बनाया?"; यह है स्क्रिप्ट किडीज़ की सहायक है जो छोटी चीज़ों के साथ ठीक हो जाती है, लेकिन जैसा कि आप देखते हैं, यह बड़ी फ़ाइलों के लिए बेकार है ...

वे लोग जो आपको StringBuilder का उपयोग करने के लिए कह रहे हैं, MSDN को अधिक बार पढ़ने की आवश्यकता है:

प्रदर्शन विचार
कॉनैट और परिशिष्ट दोनों तरीके एक मौजूदा स्ट्रिंग या StringBuilder वस्तु के लिए नया डेटा समाप्‍त करते हैं। एक स्ट्रिंग ऑब्जेक्ट कॉन्टेक्शन ऑपरेशन हमेशा मौजूदा स्ट्रिंग और नए डेटा से एक नई ऑब्जेक्ट बनाता है। एक स्ट्रिंगब्यूलर ऑब्जेक्ट नए डेटा के संघनन को समायोजित करने के लिए एक बफर रखता है। यदि कमरा उपलब्ध है, तो बफर के अंत में नया डेटा जोड़ा जाता है; अन्यथा, एक नया, बड़ा बफर आवंटित किया जाता है, मूल बफर से डेटा को नए बफर में कॉपी किया जाता है, फिर नए डेटा को नए बफर में जोड़ा जाता है। एक स्ट्रिंग या StringBuilder ऑब्जेक्ट के लिए एक कॉन्सेप्टेशन ऑपरेशन का प्रदर्शन इस बात पर निर्भर करता है कि मेमोरी आवंटन कितनी बार होता है।
एक स्ट्रिंग संयोजन ऑपरेशन हमेशा मेमोरी आवंटित करता है, जबकि एक स्ट्रिंगब्यूटेन कॉन्टेक्नेशन ऑपरेशन केवल मेमोरी आवंटित करता है, यदि नए डेटा को समायोजित करने के लिए StringBuilder ऑब्जेक्ट बफर बहुत छोटा है। नतीजतन, एक स्थिर संख्या के लिए स्ट्रिंग क्लास बेहतर है यदि स्ट्रिंग वस्तुओं की एक निश्चित संख्या को समाप्‍त किया जाता है। उस स्थिति में, अलग-अलग संघ संचालन को भी संकलक द्वारा एकल ऑपरेशन में जोड़ा जा सकता है। एक स्ट्रिंग ऑपरेशन के लिए एक स्ट्रिंगबर्ब्यूबल ऑब्जेक्ट बेहतर होता है, यदि स्ट्रिंग्स की एक मनमानी संख्या समवर्ती हो; उदाहरण के लिए, यदि एक लूप उपयोगकर्ता इनपुट के एक यादृच्छिक संख्या को समेटता है।

इसका मतलब है कि मेमोरी का बहुत बड़ा आवंटन, जो स्वैप फाइल सिस्टम का बड़ा उपयोग बन जाता है, वह रैम मेमोरी की तरह कार्य करने के लिए आपके हार्ड डिस्क ड्राइव के अनुभागों का अनुकरण करता है, लेकिन हार्ड डिस्क ड्राइव बहुत धीमी होती है।

StringBuilder विकल्प ठीक है जो एक मोनो-उपयोगकर्ता के रूप में सिस्टम का उपयोग करता है, लेकिन जब आपके पास एक ही समय में बड़ी फ़ाइलों को पढ़ने वाले दो या अधिक उपयोगकर्ता हैं, तो आपको एक समस्या है।


बाहर तुम लोग सुपर जल्दी कर रहे हैं! दुर्भाग्य से जिस तरह से मैक्रो के काम की पूरी धारा को लोड करने की आवश्यकता है। जैसा कि मैंने उल्लेख किया है कि रिचटेक्स्ट भाग के बारे में चिंता न करें। इसकी प्रारंभिक लोडिंग हम सुधार करना चाहते हैं।
निकोल ली

इसलिए आप भागों में काम कर सकते हैं, पहली एक्स लाइनें पढ़ सकते हैं, मैक्रो लागू कर सकते हैं, दूसरी एक्स लाइनें पढ़ सकते हैं, मैक्रो को लागू कर सकते हैं, और इसी तरह ... यदि आप बताते हैं कि यह मैक्रो क्या करते हैं, तो हम आपको और अधिक सटीकता के साथ मदद कर सकते हैं
टफू

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 बफर = नया char [1024]" को लूप से बाहर ले जाऊंगा: हर बार एक नया बफर बनाना आवश्यक नहीं है। बस इसे "समय से पहले" (गणना> 0) "" पर रखें।
टॉमी कार्लाइल

4

निम्नलिखित कोड स्निपेट पर एक नज़र डालें। आपने उल्लेख किया है Most files will be 30-40 MB। यह इंटेल क्वाड कोर पर 1.4 सेकंड में 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);
        }
    }
}

मूल लेख


3
इस तरह के परीक्षण कुख्यात अविश्वसनीय हैं। जब आप परीक्षण दोहराएंगे तो आप फ़ाइल सिस्टम कैश से डेटा पढ़ेंगे। यह वास्तविक परीक्षण की तुलना में तेजी से कम से कम एक क्रम है जो डिस्क से डेटा को पढ़ता है। 180 एमबी की फ़ाइल संभवतः 3 सेकंड से कम नहीं ले सकती। अपनी मशीन को रिबूट करें, असली नंबर के लिए एक बार परीक्षण चलाएं।
हंस पैसेंट

7
लाइन stringBuilder.Append संभावित रूप से खतरनाक है, आपको इसे stringBuilder.Append (fileContents, 0, charsRead) से बदलने की आवश्यकता है; यह सुनिश्चित करने के लिए कि जब धारा पहले समाप्त हो चुकी हो तब भी आप एक पूर्ण 1024 वर्ण जोड़ नहीं रहे हैं।
जोहान्स रूडॉल्फ

@JohannesRudolph, आपकी टिप्पणी ने मुझे एक बग हल कर दिया। आप 1024 नंबर के साथ कैसे आए?
20

3

आप यहाँ से मेमोरी-मैप की गई फ़ाइलों को उपयोग करने के लिए बेहतर हो सकते हैं .. स्मृति मैप की गई फ़ाइल का समर्थन .NET 4 में होगा (मुझे लगता है ... मैंने सुना है कि इसके बारे में कोई और बात कर रहा है), इसलिए यह आवरण जो p का उपयोग करता है / एक ही काम करने का आह्वान ।।

संपादित करें: पर यहाँ देखें MSDN के लिए कि यह कैसे, काम करता है यहाँ है ब्लॉग है कि यह कैसे आगामी .NET 4 में किया जाता है, जब यह रिलीज के रूप में बाहर आता है यह दर्शाता है प्रविष्टि। मैंने पहले जो लिंक दिया है वह इसे प्राप्त करने के लिए पिनवोक के आसपास एक आवरण है। आप पूरी फाइल को मेमोरी में मैप कर सकते हैं, और फाइल को स्क्रॉल करते समय स्लाइडिंग विंडो की तरह देख सकते हैं।


2

सभी उत्कृष्ट उत्तर! हालाँकि, किसी को उत्तर की तलाश में, ये कुछ हद तक अपूर्ण प्रतीत होते हैं।

एक मानक स्ट्रिंग के रूप में केवल आकार X, 2Gb से 4Gb तक आपके कॉन्फ़िगरेशन के आधार पर हो सकता है, ये उत्तर वास्तव में ओपी के प्रश्न को पूरा नहीं करते हैं। एक विधि स्ट्रिंग्स की सूची के साथ काम करना है:

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 तक प्रगति नंबर लौटाएगा, जिसका उपयोग आप अपनी प्रगति बार को अपडेट करने के लिए कर सकते हैं। एक बार लूप समाप्त हो जाने के बाद, स्ट्रिंगब्यूलर में टेक्स्ट फ़ाइल की सामग्री होगी।

इसके अलावा, क्योंकि आप पाठ चाहते हैं, हम सिर्फ बाइनरीरेडर का उपयोग पात्रों में पढ़ने के लिए कर सकते हैं, जो यह सुनिश्चित करेगा कि किसी भी मल्टी-बाइट वर्ण ( UTF-8 , UTF-16 , आदि) को पढ़ते समय आपके बफ़र्स सही ढंग से पंक्तिबद्ध हों ।

यह सब पृष्ठभूमि कार्यों, थ्रेड्स या जटिल कस्टम राज्य मशीनों का उपयोग किए बिना किया जाता है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.