एक फ़ाइल से सभी पाठ पढ़ें
Java 11 ने छोटी फ़ाइलों को पढ़ने के लिए readString () विधि को जोड़ा String
, लाइन टर्मिनेटरों को संरक्षित करना:
String content = Files.readString(path, StandardCharsets.US_ASCII);
जावा 7 और 11 के बीच संस्करणों के लिए, यहाँ एक कॉम्पैक्ट, मजबूत मुहावरा है, जो उपयोगिता पद्धति में लिपटा है:
static String readFile(String path, Charset encoding)
throws IOException
{
byte[] encoded = Files.readAllBytes(Paths.get(path));
return new String(encoded, encoding);
}
किसी फ़ाइल से पाठ की पंक्तियाँ पढ़ें
जावा 7 ने एक फ़ाइल को पाठ की पंक्तियों के रूप में पढ़ने के लिए एक सुविधा विधि जोड़ा, एक के रूप में प्रतिनिधित्व किया List<String>
। यह दृष्टिकोण "हानिपूर्ण" है क्योंकि प्रत्येक लाइन के अंत से लाइन विभाजक छीन लिए जाते हैं।
List<String> lines = Files.readAllLines(Paths.get(path), encoding);
जावा 8 ने Files.lines()
ए का उत्पादन करने की विधि जोड़ी Stream<String>
। फिर, यह विधि हानिपूर्ण है क्योंकि लाइन विभाजक छीन लिए जाते हैं। यदि IOException
फ़ाइल को पढ़ते समय कोई सामना होता है, तो इसे एक में लपेटा जाता है UncheckedIOException
, क्योंकि Stream
चेक अपवादों को फेंकने वाले लैम्ब्डा को स्वीकार नहीं करता है।
try (Stream<String> lines = Files.lines(path, encoding)) {
lines.forEach(System.out::println);
}
इसके लिए कॉल की Stream
आवश्यकता है close()
; यह एपीआई पर खराब दस्तावेज है, और मुझे संदेह है कि बहुत से लोगों के पास Stream
एक close()
विधि भी नहीं है । दिखाए गए अनुसार एआरएम-ब्लॉक का उपयोग करना सुनिश्चित करें।
यदि आप फ़ाइल के अलावा किसी स्रोत के साथ काम कर रहे हैं, तो आप इसके बजाय lines()
विधि का उपयोग कर सकते हैं BufferedReader
।
स्मृति उपयोग
पहली विधि, जो लाइन ब्रेक को संरक्षित करती है, को अस्थायी रूप से फ़ाइल के आकार के लिए कई बार मेमोरी की आवश्यकता हो सकती है, क्योंकि थोड़े समय के लिए कच्ची फ़ाइल सामग्री (एक बाइट सरणी), और डीकोड किए गए अक्षर (जिनमें से प्रत्येक 16 बिट्स भी एन्कोडेड है के रूप में फ़ाइल में 8 बिट) एक ही बार में स्मृति में रहते हैं। यह उन फ़ाइलों पर लागू करने के लिए सबसे सुरक्षित है जिन्हें आप उपलब्ध स्मृति के सापेक्ष छोटा होना जानते हैं।
दूसरी विधि, रीडिंग लाइन्स, आमतौर पर अधिक मेमोरी कुशल होती है, क्योंकि डिकोडिंग के लिए इनपुट बाइट बफर को पूरी फाइल को समाहित करने की आवश्यकता नहीं होती है। हालाँकि, यह अभी भी उन फ़ाइलों के लिए उपयुक्त नहीं है जो उपलब्ध मेमोरी के सापेक्ष बहुत बड़ी हैं।
बड़ी फ़ाइलों को पढ़ने के लिए, आपको अपने प्रोग्राम के लिए एक अलग डिज़ाइन की आवश्यकता होती है, एक जो किसी स्ट्रीम से पाठ का एक हिस्सा पढ़ता है, उसे संसाधित करता है, और फिर उसी निश्चित-आकार के मेमोरी ब्लॉक का पुन: उपयोग करते हुए आगे बढ़ता है। यहां, "बड़े" कंप्यूटर चश्मा पर निर्भर करता है। आजकल, यह सीमा कई गीगाबाइट रैम हो सकती है। तीसरी विधि, इसका उपयोग करने Stream<String>
का एक तरीका है, यदि आपका इनपुट "रिकॉर्ड" व्यक्तिगत रेखाओं के रूप में होता है। (इस readLine()
पद्धति का उपयोग करना BufferedReader
इस दृष्टिकोण के बराबर प्रक्रियात्मक है।)
अक्षरों को सांकेतिक अक्षरों में बदलना
मूल पोस्ट में नमूने से गायब होने वाली एक चीज चरित्र एन्कोडिंग है। कुछ विशेष मामले हैं जहां प्लेटफ़ॉर्म डिफ़ॉल्ट वह है जो आप चाहते हैं, लेकिन वे दुर्लभ हैं, और आपको अपनी पसंद को सही ठहराने में सक्षम होना चाहिए।
StandardCharsets
वर्ग सभी जावा runtimes के लिए आवश्यक एन्कोडिंग के लिए कुछ स्थिरांक को परिभाषित:
String content = readFile("test.txt", StandardCharsets.UTF_8);
मंच डिफ़ॉल्ट से उपलब्ध है वर्ग में ही:Charset
String content = readFile("test.txt", Charset.defaultCharset());
नोट: यह उत्तर काफी हद तक मेरे जावा 6 संस्करण को बदल देता है। Java 7 की उपयोगिता सुरक्षित रूप से कोड को सरल करती है, और पुराने उत्तर, जो एक मैप्ड बाइट बफर का उपयोग करता है, उस फाइल को रोक दिया जाता है, जिसे मैप किए गए बफर को कचरा एकत्र होने तक पढ़ने से हटा दिया जाता है। आप इस उत्तर पर "संपादित" लिंक के माध्यम से पुराने संस्करण को देख सकते हैं।