Go में फ़ाइल लाइन दर लाइन पढ़ना: शुरुआत से एक्सपर्ट तक (2025)
\n\nक्या आपने कभी सोचा है कि Go में बड़ी लॉग फ़ाइलों या CSV डेटा को कुशलता से कैसे पढ़ा जाए? अगर हाँ, तो आप सही जगह पर हैं। फ़ाइल को लाइन दर लाइन पढ़ना Stack Overflow पर सबसे लोकप्रिय विषयों में से एक है, और यह कोई संयोग नहीं है। Go हमें शक्तिशाली टूल्स देता है, लेकिन सही तरीका चुनना कभी-कभी मुश्किल हो सकता है।
\n\nइस लेख में, हम सिर्फ़ यह नहीं दिखाएंगे कि फ़ाइल से लाइनें कैसे पढ़ी जाती हैं। हम 2025 की बेस्ट प्रैक्टिसेज़ पर चर्चा करेंगे: तेज़ bufio.Scanner से लेकर कस्टम बफ़र वाले सॉल्यूशंस तक। आप सीखेंगे कि कैसे सामान्य गलतियों (जैसे 64KB से लंबी लाइनें) से बचें, एरर को सही तरीके से हैंडल करें, और बड़े डेटा के साथ काम को तेज़ करें।
तैयार हैं? चलिए शुरू करते हैं!
\n\nलाइन पढ़ना सिर्फ़ "पढ़ो और खत्म" नहीं है, क्यों?
\n\nGo में फ़ाइलें पढ़ने के कई तरीके हैं, और हर एक किसी खास काम के लिए है। कोई ioutil.ReadFile का उपयोग करता है (वैसे, Go 1.16 से यह deprecated है), तो कोई os.File को बफ़र के साथ इस्तेमाल करता है। लेकिन लाइन-बाय-लाइन प्रोसेसिंग के लिए राजा है bufio.Scanner।
क्यों? क्योंकि यह:
\n- \n
- मेमोरी में कुशल — पूरी फ़ाइल को RAM में लोड नहीं करता \n
- उपयोग में आसान — बहुत कम कोड चाहिए \n
- एरर हैंडल कर सकता है — हर स्टेप की जाँच करता है \n
लेकिन एक बारीकी है: Scanner का डिफ़ॉल्ट बफ़र 64 KB है। अगर आपकी लाइन इससे लंबी है, तो आपको एरर मिलेगी। ऐसे मामलों के लिए दूसरे तरीकों की ज़रूरत होती है।
\n\nबेसिक उदाहरण: bufio.Scanner
\n\nचलिए सबसे आम तरीके से शुरू करते हैं। यह रहा न्यूनतम काम करने वाला कोड:
\n\npackage main\n\nimport (\n "bufio"\n "fmt"\n "log"\n "os"\n)\n\nfunc main() {\n file, err := os.Open("data.txt")\n if err != nil {\n log.Fatal(err)\n }\n defer file.Close()\n\n scanner := bufio.NewScanner(file)\n for scanner.Scan() {\n line := scanner.Text()\n fmt.Println(line)\n }\n\n if err := scanner.Err(); err != nil {\n log.Fatal(err)\n }\n}\n\n\nयहाँ क्या महत्वपूर्ण है?
\n- \n
defer file.Close()— पैनिक होने पर भी फ़ाइल बंद करता है \n scanner.Text()— न्यू लाइन कैरेक्टर (\\n) के बिना स्ट्रिंग लौटाता है \n scanner.Err()— जाँचता है कि पढ़ने के दौरान कोई एरर तो नहीं आई \n
यह कोड 90% कामों के लिए परफेक्ट है: कॉन्फ़िग फ़ाइलें, लॉग्स, छोटी CSV फ़ाइलें।
\n\nलंबी लाइनों की समस्या: बफ़र बढ़ाना
\n\nसोचिए: आप 100 KB की JSON लाइनों वाली फ़ाइल पढ़ रहे हैं। Scanner bufio.Scanner: token too long एरर के साथ फेल हो जाएगा। हल — बफ़र बढ़ाना:
scanner := bufio.NewScanner(file)\nbuf := make([]byte, 0, 1024*1024) // 1 MB\nscanner.Buffer(buf, 10*1024*1024) // अधिकतम 10 MB प्रति लाइन\n\nfor scanner.Scan() {\n // ... प्रोसेसिंग\n}\n\n\nमहत्वपूर्ण: दूसरा पैरामीटर लाइन का अधिकतम आकार है। अगर लाइन इससे बड़ी है, तो फिर से एरर आएगी। थोड़ा अतिरिक्त रखें, लेकिन बहुत ज़्यादा नहीं — मेमोरी असीमित नहीं है।
\n\nजब Scanner काम नहीं करता: विकल्प
\n\nलोकप्रियता के बावजूद, bufio.Scanner हर स्थिति के लिए नहीं है। यहाँ दो मामले हैं जब दूसरे तरीके के बारे में सोचना चाहिए:
1. बहुत बड़ी फ़ाइलें (गीगाबाइट्स)
\nअगर फ़ाइल उपलब्ध मेमोरी से बड़ी है (दुर्लभ, लेकिन हो सकता है), Scanner अभी भी अच्छा है। लेकिन अगर आपको बाइनरी डेटा पढ़ना है या कस्टम सेपरेटर वाली लाइनें प्रोसेस करनी हैं, तो bufio.Reader का उपयोग करना बेहतर है:
reader := bufio.NewReader(file)\nfor {\n line, err := reader.ReadString('\\n')\n if err != nil {\n break\n }\n // लाइन के अंत में \\n होता है\n line = strings.TrimRight(line, "\\n")\n fmt.Println(line)\n}\n\n\nफ़ायदा: आप हर रीड ऑपरेशन को कंट्रोल करते हैं। नुकसान: ज़्यादा कोड और एरर का ज़्यादा जोखिम।
\n\n2. मेमोरी में लोड किए बिना प्रोसेसिंग
\nकभी-कभी सिर्फ़ लाइनें गिननी हों या कोई पैटर्न ढूंढना हो। इसके लिए bufio.Scanner काफी है।