जावा में फ़ाइल को स्ट्रिंग में कैसे पढ़ें: अंदरूनी विश्लेषण

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

जावा में फ़ाइल को स्ट्रिंग में कैसे पढ़ें: Stack Overflow के लोकप्रिय प्रश्न का विश्लेषण

\n\n

यदि आपने कभी सोचा है कि "How do I create a Java string from the contents of a file?" — तो आप अकेले नहीं हैं। इस प्रश्न को Stack Overflow पर हज़ारों बार देखा गया है, और यह उचित भी है। एक सामान्य कार्य — टेक्स्ट फ़ाइल को पढ़ना और उसकी सामग्री को स्ट्रिंग में रखना — में कई छिपी समस्याएँ हैं: मेमोरी लीक से लेकर एन्कोडिंग समस्याओं तक।

\n\n

इस लेख में हम केवल तैयार समाधान नहीं देंगे। हम प्रत्येक विधि के अंदरूनी तंत्र को देखेंगे: BufferedReader कैसे काम करता है, Files.readString() केवल Java 11 में क्यों आया, और Scanner, InputStream से कैसे अलग है। चलिए शुरू करते हैं!

\n\n

यह जितना लगता है उससे अधिक जटिल क्यों है?

\n\n

पहली नज़र में, कार्य सरल है: एक फ़ाइल है, एक स्ट्रिंग है। लेकिन Java एक सख्त टाइपिंग और प्रबंधित मेमोरी वाली भाषा है। फ़ाइल पढ़ने के लिए, आपको चाहिए:

\n\n
    \n
  • डेटा स्ट्रीम खोलना (InputStream, Reader)
  • \n
  • पढ़ने को बफ़र करना (हर बाइट के लिए डिस्क को हिट करने से बचने के लिए)
  • \n
  • बाइट्स/कैरेक्टर्स को एक बफ़र में इकट्ठा करना
  • \n
  • एन्कोडिंग को ध्यान में रखते हुए स्ट्रिंग में बदलना
  • \n
  • संसाधनों को बंद करना (फ़ाइल डिस्क्रिप्टर लीक से बचने के लिए)
  • \n
\n\n

इनमें से प्रत्येक चरण विफलता का एक संभावित बिंदु है। आइए सबसे लोकप्रिय तरीकों को समझते हैं।

\n\n

विधि 1: क्लासिक — BufferedReader (Java 1.1+)

\n\n

सबसे पुरानी और सिद्ध विधि। यह पंक्ति-दर-पंक्ति पढ़ने के लिए BufferedReader का उपयोग करती है। अंदरूनी तौर पर, एक बफ़र (डिफ़ॉल्ट रूप से 8 KB) डेटा जमा करता है, जिससे read() सिस्टम कॉल की संख्या कम हो जाती है।

\n\n
public static String readFileBufferedReader(String filePath) throws IOException {\n    StringBuilder content = new StringBuilder();\n    try (BufferedReader reader = new BufferedReader(new FileReader(filePath, StandardCharsets.UTF_8))) {\n        String line;\n        while ((line = reader.readLine()) != null) {\n            content.append(line).append(System.lineSeparator());\n        }\n    }\n    return content.toString();\n}
\n\n

यह अंदरूनी तौर पर कैसे काम करता है?

\n

FileReader फ़ाइल खोलता है और FileInputStream बनाता है। BufferedReader इसे लपेटता है, एक बफ़र जोड़ता है। readLine() कॉल करने पर, डेटा का एक ब्लॉक (जैसे, 8 KB) पढ़ा जाता है, और बफ़र से स्ट्रिंग बनाई जाती है। यदि स्ट्रिंग बफ़र से लंबी है, तो बफ़र फिर से पढ़ा जाता है। try-with-resources अपवाद होने पर भी स्ट्रीम को बंद करने की गारंटी देता है।

\n\n

लाभ: Java के किसी भी संस्करण पर काम करता है, नियंत्रित पंक्ति-दर-पंक्ति पढ़ना।
\nनुकसान: अंत में एक अतिरिक्त लाइन सेपरेटर जोड़ता है, बहुत बड़ी फ़ाइलों के लिए अक्षम (मेमोरी में स्ट्रिंग)।

\n\n

विधि 2: Scanner — सुविधाजनक लेकिन धीमा (Java 5+)

\n\n

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

\n\n
public static String readFileScanner(String filePath) throws IOException {\n    try (Scanner scanner = new Scanner(new File(filePath), StandardCharsets.UTF_8.name())) {\n        scanner.useDelimiter("\\\\A"); // फ़ाइल की शुरुआत को विभाजक के रूप में\n        return scanner.hasNext() ? scanner.next() : "";\n    }\n}
\n\n

\\\\A का जादू: यह एक रेगुलर एक्सप्रेशन है जो इनपुट डेटा की शुरुआत को दर्शाता है। इसे विभाजक के रूप में सेट करके, हम Scanner को एक बार में पूरी सामग्री पढ़ने के लिए मजबूर करते हैं। अंदरूनी तौर पर, Scanner विभाजक खोजने के लिए Pattern का उपयोग करता है, जो रेगुलर एक्सप्रेशन पर अतिरिक्त ओवरहेड जोड़ता है।

\n\n

लाभ: बहुत संक्षिप्त कोड।
\nनुकसान: रेगुलर एक्सप्रेशन के कारण BufferedReader से धीमा, बाइनरी फ़ाइलों के लिए उपयुक्त नहीं।

\n\n

विधि 3: Files.readAllLines() — Java 8 की सुविधा (NIO)

\n\n

Java 8 से शुरू होकर, पैकेज java.nio.file ने एक सुरुचिपूर्ण

ब्लॉग

पुस्तक अनुशंसाएँ