मैं एक फ़ाइल की सामग्री से जावा स्ट्रिंग कैसे बना सकता हूं?


1513

मैं पिछले कुछ समय से मुहावरे का उपयोग कर रहा हूं। और यह सबसे अधिक फैला हुआ लगता है, कम से कम उन साइटों पर जो मैंने दौरा किया है।

क्या जावा में एक स्ट्रिंग में एक फ़ाइल को पढ़ने का एक बेहतर / अलग तरीका है?

private String readFile(String file) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader (file));
    String         line = null;
    StringBuilder  stringBuilder = new StringBuilder();
    String         ls = System.getProperty("line.separator");

    try {
        while((line = reader.readLine()) != null) {
            stringBuilder.append(line);
            stringBuilder.append(ls);
        }

        return stringBuilder.toString();
    } finally {
        reader.close();
    }
}

7
क्या कोई मुझे बहुत सरल तरीके से समझा सकता है कि NIO के साथ क्या है? हर बार जब मैं इसके बारे में पढ़ता हूं तो मैं चैनल के nth उल्लेख में खो जाता हूं :(
OscarRyz

7
याद रखें कि यह गारंटी नहीं है कि फ़ाइल का लाइन विभाजक सिस्टम के लाइन विभाजक के समान आवश्यक नहीं है।
हेनरिक पॉल

138
क्या आप कृपया एक उचित कोशिश अंत में सम्मिलित कर सकते हैं जो पाठक को बंद कर दे? कोई वास्तव में इस उदाहरण का उपयोग कर सकता है और अपने कोड में एक बग को पेश कर सकता है।
हंस-पीटर स्टॉरर

6
ऊपर कोड में अंतिम पंक्ति में अतिरिक्त नई लाइन चार जोड़ने की एक बग है। यह कुछ इस तरह होना चाहिए अगर (पंक्ति = Reader.readLine ())! = Null) {stringBuilder.append (लाइन); } जबकि (लाइन = Reader.readLine ())! = null) {stringBuilder.append (ls); stringBuilder.append (लाइन); }
दीप

27
जावा 7 byte[] Files.readAllBytes(file);उन लोगों से परिचय कराता है , जो 'वन-लाइन' स्कैनर समाधान का सुझाव देते हैं: क्या इसे बंद करने की आवश्यकता नहीं है?
वैल

जवाबों:


1533

एक फ़ाइल से सभी पाठ पढ़ें

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 की उपयोगिता सुरक्षित रूप से कोड को सरल करती है, और पुराने उत्तर, जो एक मैप्ड बाइट बफर का उपयोग करता है, उस फाइल को रोक दिया जाता है, जिसे मैप किए गए बफर को कचरा एकत्र होने तक पढ़ने से हटा दिया जाता है। आप इस उत्तर पर "संपादित" लिंक के माध्यम से पुराने संस्करण को देख सकते हैं।


3
तकनीकी रूप से, यह समय और स्थान में O (n) है। गुणात्मक रूप से, स्ट्रिंग्स की अपरिवर्तनीय आवश्यकता के कारण, यह मेमोरी पर बहुत कठिन है; अस्थायी रूप से मेमोरी में चार डेटा की दो प्रतियां हैं, साथ ही एन्कोडेड बाइट्स के लिए कमरा। कुछ एकल-बाइट एन्कोडिंग को मानते हुए, यह (अस्थायी रूप से) फ़ाइल में प्रत्येक वर्ण के लिए 5 बाइट्स मेमोरी की आवश्यकता होगी। चूँकि यह प्रश्न विशेष रूप से एक स्ट्रिंग के लिए पूछता है, वही मैं दिखाता हूं, लेकिन यदि आप "डिकोड" द्वारा लौटाए गए चारबफ़र के साथ काम कर सकते हैं, तो मेमोरी की आवश्यकता बहुत कम है। समय के लिहाज से, मुझे नहीं लगता कि आपको कोर जावा लिबास में तेजी से कुछ मिलेगा।
इरिकसन

5
संभव टाइपो? NIO में java.nio.charset.Charset नामक एक चारसेट (चारसेट नहीं) वर्ग है। क्या यह चारसेट होना चाहिए था?
जोनाथन राइट

31
नोट: उस कोड को थोड़ा सा प्रयोग करने के बाद, मुझे पता चला कि आप इस विधि से पढ़ने के बाद फ़ाइल को सही तरीके से हटा नहीं सकते हैं, जो किसी मामले में एक गैर मुद्दा हो सकता है, लेकिन मेरा नहीं। क्या यह इस मुद्दे के संबंध में हो सकता है: Bugs.sun.com/bugdatabase/view_bug.do?bug_id=4715154 ? मैं अंत में जॉन स्कीट के प्रस्ताव के साथ गया जो इस बग से ग्रस्त नहीं है। वैसे भी, मैं सिर्फ जानकारी देना चाहता था, अन्य लोगों के लिए, बस मामले में ...
सेबेस्टियन नुसाउबूमर

5
@ Sébastien Nussbaumer: मैं भी इस समस्या से टकरा गया। कमाल है कि बग को "विल नॉट फिक्स" के रूप में चिह्नित किया गया है। यह अनिवार्य रूप से इसका मतलब है कि FileChannel#mapसामान्य तौर पर, अनुपयोगी है।
जूनास पुलका

4
@ Sébastien Nussbaumer: बग को Oracle / Sun Bug डेटाबेस से हटा दिया गया है: "यह बग उपलब्ध नहीं है।" Google ने इस साइट को webcache.googleusercontent.com/search?q=cache:bugs.sun.com/…
bobndrew

350

यदि आप बाहरी पुस्तकालय का उपयोग करने के इच्छुक हैं, तो Apache Commons IO (200KB JAR) देखें। यह एक में शामिल है org.apache.commons.io.FileUtils.readFileToString()विधि है कि आप एक पूरे पढ़ने के लिए अनुमति देता है Fileएक में Stringकोड की एक लाइन के साथ।

उदाहरण:

import java.io.*;
import java.nio.charset.*;
import org.apache.commons.io.*;

public String readFile() throws IOException {
    File file = new File("data.txt");
    return FileUtils.readFileToString(file, StandardCharsets.UTF_8);
}

मुझे आपके द्वारा प्रदत्त URL में वह विधि नहीं मिली।
ऑस्कररेज़

2
यह कक्षा में है। org.apache.commons.io.FileUtils
Cyrille Ka

2
मैं FileUtils का उपयोग कर रहा हूं, लेकिन मैं सोच रहा हूं कि FileUtils या स्वीकृत nio उत्तर का उपयोग करके बेहतर betwwen क्या है?
गिल्लाउप

4
@ गिलियूम: सबसे बड़ा सवाल यह है कि क्या आप थर्ड पार्टी लाइब्रेरी पर निर्भरता रखने में सहज हैं। यदि आपके पास अपनी परियोजना में कॉमन्स IO या अमरूद है, तो इसका उपयोग करें (बस कोड सादगी के लिए, अन्यथा संभावना ध्यान देने योग्य अंतर नहीं होगा)।
जोनीक

183

पर आधारित एक बहुत ही दुबला समाधान Scanner:

Scanner scanner = new Scanner( new File("poem.txt") );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block

या, यदि आप चारसेट सेट करना चाहते हैं:

Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" );
String text = scanner.useDelimiter("\\A").next();
scanner.close(); // Put this call in a finally block

या, एक कोशिश के साथ-संसाधन ब्लॉक के साथ, जो scanner.close()आपके लिए कॉल करेगा :

try (Scanner scanner = new Scanner( new File("poem.txt"), "UTF-8" )) {
    String text = scanner.useDelimiter("\\A").next();
}

याद रखें कि Scannerकंस्ट्रक्टर एक फेंक सकता है IOException। और आयात करने के लिए मत भूलना java.ioऔर java.util

स्रोत: पैट नीमेयर का ब्लॉग


4
\\ एक काम करता है क्योंकि "फ़ाइल की अन्य शुरुआत" नहीं है, इसलिए आप वास्तव में आखिरी टोकन पढ़ते हैं ... जो कि पहला भी है। \\ Z के साथ कभी नहीं की कोशिश की। यह भी ध्यान रखें कि आप कुछ भी पढ़ सकते हैं, जैसे कि फ़ाइलें, इनपुटस्ट्रीम, चैनल ... मैं कभी-कभी इस कोड का उपयोग ग्रहण की प्रदर्शन विंडो से पढ़ने के लिए करता हूं, जब मुझे यकीन नहीं होता कि मैं एक फ़ाइल या किसी अन्य को पढ़ रहा हूं .. .हाँ, क्लासपाथ मुझे भ्रमित करता है।
पाब्लो ग्रिसफ़ी

1
पोस्टर के रूप में, मैं कह सकता हूं कि मैं वास्तव में नहीं जानता कि क्या और जब फ़ाइल ठीक से बंद है ... मैं इसे उत्पादन कोड में कभी नहीं लिखता, मैं इसे केवल परीक्षणों या डिबग के लिए उपयोग करता हूं।
पाब्लो ग्रिसफ़ी

2
मुझे लगता है कि मेरे पास 1024 वर्णों की एक सीमा है
Whimusical

20
स्कैनर क्लोजेबल लागू होता है (यह स्रोत पर करीब आ जाता है) - इसलिए सुरुचिपूर्ण होने के बावजूद यह वास्तव में एक-लाइनर नहीं होना चाहिए। बफर का डिफ़ॉल्ट आकार 1024 है, लेकिन स्कैनर आकार को आवश्यकतानुसार बढ़ा देगा (देखें स्कैनर # मेकस्पेस ())
इयरकैम

8
यह एक के साथ खाली फ़ाइलों के लिए विफल रहता है java.util.NoSuchElementException
स्पेसट्रैक

116
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

String content = new String(Files.readAllBytes(Paths.get("readMe.txt")), StandardCharsets.UTF_8);

जावा 7 के बाद से आप इसे इस तरह से कर सकते हैं।


इसे उत्तर के रूप में स्वीकार किया जाना चाहिए - एकल पंक्ति, कोई बाहरी परिवाद नहीं।
चेरी

इसने एक नई पंक्ति को अंत में जोड़ा, भले ही वह फाइल में मौजूद न हो
स्टीफन हेबरल

79

यदि आप एक ऐसे विकल्प की तलाश कर रहे हैं जिसमें तृतीय-पक्ष लाइब्रेरी शामिल नहीं है (जैसे कॉमन्स I / O ), तो आप स्कैनर वर्ग का उपयोग कर सकते हैं :

private String readFile(String pathname) throws IOException {

    File file = new File(pathname);
    StringBuilder fileContents = new StringBuilder((int)file.length());        

    try (Scanner scanner = new Scanner(file)) {
        while(scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine() + System.lineSeparator());
        }
        return fileContents.toString();
    }
}

2
मुझे लगता है कि यह सबसे अच्छा तरीका है। की जाँच करें java.sun.com/docs/books/tutorial/essential/io/scanning.html
Tarski

3
स्कैनर निर्माणकर्ता जो स्ट्रिंग को स्वीकार करता है, वह स्ट्रिंग को पढ़ने के लिए किसी फ़ाइल के नाम के रूप में नहीं मानता है, लेकिन स्कैन किए जाने वाले पाठ के रूप में। मैं हर समय वह गलती करता हूं। : - /
एलन मूर

@ एलन, अच्छी पकड़। मैंने डॉन के जवाब को थोड़ा ठीक किया (मुझे उम्मीद है)।
जोनिक

3
fileContents.append (scanner.nextLine ()) संलग्न (lineSeparator)।
प्रतिबंध-जियोइंजीनियरिंग

1
प्रारंभ कथन को बदलें Scanner scanner = new Scanner((Readable) new BufferedReader(new FileReader(file)));। अन्यथा आप केवल फ़ाइल के हिस्से को पकड़ सकते हैं।
वी यांग

71

अमरूद में कॉमन्स IOUtils की तरह ही एक विधि है जिसका विली औस रोहर ने उल्लेख किया है:

import com.google.common.base.Charsets;
import com.google.common.io.Files;

// ...

String text = Files.toString(new File(path), Charsets.UTF_8);

PiggyPiglet द्वारा EDIT
Files#toString को हटा दिया गया है, और ऑक्टोबोर 2019 को हटाने के कारण। इसके बजाय उपयोग करें Files.asCharSource(new File(path), StandardCharsets.UTF_8).read();

EDIT ऑस्कर रेयेस द्वारा

यह उद्धृत पुस्तकालय पर अंतर्निहित (सरलीकृत) अंतर्निहित कोड है:

InputStream in = new FileInputStream(file);
byte[] b  = new byte[file.length()];
int len = b.length;
int total = 0;

while (total < len) {
  int result = in.read(b, total, len - total);
  if (result == -1) {
    break;
  }
  total += result;
}

return new String( b , Charsets.UTF_8 );

संपादित करें (जोनिक द्वारा): उपरोक्त हाल के अमरूद संस्करणों के स्रोत कोड से मेल नहीं खाता है। वर्तमान स्रोत के लिए, com.google.common.io पैकेज में कक्षाएं फाइलें , चारस्ट्रीम , बाइटसोर्स और चारसोर्स देखें


इस कोड में लंबे समय से इंट के लिए कास्टिंग है जो बड़ी फ़ाइलों के साथ कुछ पागल व्यवहार को पॉप कर सकता है। अतिरिक्त स्थान हैं और आप इनपुटस्ट्रीम को कहां बंद करते हैं?
मोहम्मद ताहिर अलरफ़ी

@MTA: धारा है बंद कर दिया, ध्यान दें के उपयोग Closerमें CharSource । उत्तर में कोड वास्तविक, वर्तमान अमरूद स्रोत नहीं है।
जोनीक

54
import java.nio.file.Files;

.......

 String readFile(String filename) {
            File f = new File(filename);
            try {
                byte[] bytes = Files.readAllBytes(f.toPath());
                return new String(bytes,"UTF-8");
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return "";
    }

6
या इससे भी अधिक सरल:new String(Files.readAllBytes(FileSystems.getDefault().getPath( filename)));

12
या new String(Files.readAllBytes(Paths.get(filename)));:-)
assafmo

1
अच्छी तरह से खेला जाता है, और अगले लड़के को बचाने के लिए, Pathsजाहिरा तौर पर 1.7+ है FileSystems। (इसे डांग!)
रफिन

4
यह, शर्म की बात है कि इस जवाब में अधिक वोट नहीं हैं। मैं एक स्ट्रिंग में एक पाठ फ़ाइल प्राप्त करने का सबसे तेज और सरल तरीका ढूंढ रहा था। यह वह है और अगर मैं नीचे और नीचे और नीचे स्क्रॉल नहीं करता, तो मैं इसे याद करता। ओपी को शीर्ष पर ले जाने के लिए इस जवाब को स्वीकार करने पर विचार करना चाहिए।
कांटा

@ इस उत्तर में भयानक त्रुटि हैंडलिंग है। उत्पादन विधि में इस विधि का उपयोग न करें, या बेहतर: कभी नहीं।
xehpuk

51

यदि आपको एक स्ट्रिंग प्रसंस्करण (समानांतर प्रसंस्करण) की आवश्यकता है तो जावा 8 में महान स्ट्रीम एपीआई है।

String result = Files.lines(Paths.get("file.txt"))
                    .parallel() // for parallel processing 
                    .map(String::trim) // to change line   
                    .filter(line -> line.length() > 2) // to filter some lines by a predicate                        
                    .collect(Collectors.joining()); // to join lines

अधिक उदाहरण JDK नमूनों में उपलब्ध हैं जिन्हें Oracle Java SE 8 डाउनलोड पृष्ठsample/lambda/BulkDataOperations से डाउनलोड किया जा सकता है

एक और एक लाइनर उदाहरण

String out = String.join("\n", Files.readAllLines(Paths.get("file.txt")));

क्या आपके द्वारा लाइनों या उससे पहले पढ़ने के बाद। समानांतर () होता है?
इस्तवान

टर्मिनल ऑपरेशन कलेक्ट (...) लागू होने के बाद से वास्तविक काम शुरू होता है। स्ट्रीम लाइन द्वारा लाइन की गई आबादी है। प्रसंस्करण से पहले मेमोरी में पूरी फ़ाइल पढ़ने की आवश्यकता नहीं है (जैसे फ़िल्टरिंग और मैपिंग)।
आंद्रेई एन

गैर-खाली लाइनों को चुनने से पहले ट्रिम करें?
थोरबजोरन रावन एंडरसन

50

वह कोड लाइन ब्रेक को सामान्य करेगा, जो आप वास्तव में करना चाहते हैं या नहीं हो सकता है।

यहाँ एक विकल्प है जो ऐसा नहीं करता है, और जो (IMO) NIO कोड की तुलना में समझने में सरल है (हालाँकि यह अभी भी उपयोग करता है java.nio.charset.Charset):

public static String readFile(String file, String csName)
            throws IOException {
    Charset cs = Charset.forName(csName);
    return readFile(file, cs);
}

public static String readFile(String file, Charset cs)
            throws IOException {
    // No real need to close the BufferedReader/InputStreamReader
    // as they're only wrapping the stream
    FileInputStream stream = new FileInputStream(file);
    try {
        Reader reader = new BufferedReader(new InputStreamReader(stream, cs));
        StringBuilder builder = new StringBuilder();
        char[] buffer = new char[8192];
        int read;
        while ((read = reader.read(buffer, 0, buffer.length)) > 0) {
            builder.append(buffer, 0, read);
        }
        return builder.toString();
    } finally {
        // Potential issue here: if this throws an IOException,
        // it will mask any others. Normally I'd use a utility
        // method which would log exceptions and swallow them
        stream.close();
    }        
}

1
मुझे इस पुरानी टिप्पणी को पुनर्जीवित करने के लिए क्षमा करें, लेकिन क्या आपका मतलब "फ़ाइल" नामक स्ट्रिंग ऑब्जेक्ट में पास करना है, या इसके बजाय एक फ़ाइल ऑब्जेक्ट होना चाहिए?
ब्रायन लार्सन

28

फ़ाइल को डिस्क या नेटवर्क से स्ट्रिंग के रूप में पढ़ने के सभी संभावित तरीकों को इकट्ठा किया।

  • अमरूद: Google कक्षाओं का उपयोग करते हुए Resources,Files

    static Charset charset = com.google.common.base.Charsets.UTF_8;
    public static String guava_ServerFile( URL url ) throws IOException {
        return Resources.toString( url, charset );
    }
    public static String guava_DiskFile( File file ) throws IOException {
        return Files.toString( file, charset );
    }

  • APACHE - कक्षा IOUtils, FileUtils का उपयोग कर कॉमन्स IO

    static Charset encoding = org.apache.commons.io.Charsets.UTF_8;
    public static String commons_IOUtils( URL url ) throws IOException {
        java.io.InputStream in = url.openStream();
        try {
            return IOUtils.toString( in, encoding );
        } finally {
            IOUtils.closeQuietly(in);
        }
    }
    public static String commons_FileUtils( File file ) throws IOException {
        return FileUtils.readFileToString( file, encoding );
        /*List<String> lines = FileUtils.readLines( fileName, encoding );
        return lines.stream().collect( Collectors.joining("\n") );*/
    }

  • स्ट्रीम एपीआई का उपयोग कर जावा 8 बफरर

    public static String streamURL_Buffer( URL url ) throws IOException {
        java.io.InputStream source = url.openStream();
        BufferedReader reader = new BufferedReader( new InputStreamReader( source ) );
        //List<String> lines = reader.lines().collect( Collectors.toList() );
        return reader.lines().collect( Collectors.joining( System.lineSeparator() ) );
    }
    public static String streamFile_Buffer( File file ) throws IOException {
        BufferedReader reader = new BufferedReader( new FileReader( file ) );
        return reader.lines().collect(Collectors.joining(System.lineSeparator()));
    }

  • रेगेक्स के साथ स्कैनर क्लास \A। जो इनपुट की शुरुआत से मेल खाता है।

    static String charsetName = java.nio.charset.StandardCharsets.UTF_8.toString();
    public static String streamURL_Scanner( URL url ) throws IOException {
        java.io.InputStream source = url.openStream();
        Scanner scanner = new Scanner(source, charsetName).useDelimiter("\\A");
        return scanner.hasNext() ? scanner.next() : "";
    }
    public static String streamFile_Scanner( File file ) throws IOException {
        Scanner scanner = new Scanner(file, charsetName).useDelimiter("\\A");
        return scanner.hasNext() ? scanner.next() : "";
    }

  • जावा 7 ( java.nio.file.Files.readAllBytes)

    public static String getDiskFile_Java7( File file ) throws IOException {
        byte[] readAllBytes = java.nio.file.Files.readAllBytes(Paths.get( file.getAbsolutePath() ));
        return new String( readAllBytes );
    }

  • BufferedReaderका उपयोग कर InputStreamReader

    public static String getDiskFile_Lines( File file ) throws IOException {
        StringBuffer text = new StringBuffer();
        FileInputStream fileStream = new FileInputStream( file );
        BufferedReader br = new BufferedReader( new InputStreamReader( fileStream ) );
        for ( String line; (line = br.readLine()) != null; )
            text.append( line + System.lineSeparator() );
        return text.toString();
    }

उपरोक्त विधियों तक पहुंचने के लिए मुख्य विधि के साथ उदाहरण।

public static void main(String[] args) throws IOException {
    String fileName = "E:/parametarisation.csv";
    File file = new File( fileName );

    String fileStream = commons_FileUtils( file );
            // guava_DiskFile( file );
            // streamFile_Buffer( file );
            // getDiskFile_Java7( file );
            // getDiskFile_Lines( file );
    System.out.println( " File Over Disk : \n"+ fileStream );


    try {
        String src = "https://code.jquery.com/jquery-3.2.1.js";
        URL url = new URL( src );

        String urlStream = commons_IOUtils( url );
                // guava_ServerFile( url );
                // streamURL_Scanner( url );
                // streamURL_Buffer( url );
        System.out.println( " File Over Network : \n"+ urlStream );
    } catch (MalformedURLException e) {
        e.printStackTrace();
    }
}

@देख


26

यदि यह एक पाठ फ़ाइल है तो अपाचे कॉमन्स-आईओ का उपयोग क्यों न करें ?

इसकी निम्न विधि है

public static String readFileToString(File file) throws IOException

यदि आप एक सूची के उपयोग के रूप में लाइनें चाहते हैं

public static List<String> readLines(File file) throws IOException

25

JDK 11 के बाद से:

String file = ...
Path path = Paths.get(file);
String content = Files.readString(path);
// Or readString(path, someCharset), if you need a Charset different from UTF-8

क्यों, ओह क्यों, नए तरीकों को पेश करें जो 2018 में डिफ़ॉल्ट चारसेट पर भरोसा करते हैं?
मारीयन

2
@ इस विधि डिफ़ॉल्ट सिस्टम charset पर भरोसा नहीं करता है। यह UTF-8 के लिए चूक है, यह ठीक है।
लेवेंटोव

@ लेवेंटोव आप सही कह रहे हैं! इतना Files.readAllLines करता है! वह फ़ाइल API को पुराने तरीकों के अनुरूप नहीं बनाता है लेकिन यह बेहतर के लिए है :)
mryan

17

किसी फ़ाइल को बाइनरी के रूप में पढ़ने और अंत में परिवर्तित करने के लिए

public static String readFileAsString(String filePath) throws IOException {
    DataInputStream dis = new DataInputStream(new FileInputStream(filePath));
    try {
        long len = new File(filePath).length();
        if (len > Integer.MAX_VALUE) throw new IOException("File "+filePath+" too large, was "+len+" bytes.");
        byte[] bytes = new byte[(int) len];
        dis.readFully(bytes);
        return new String(bytes, "UTF-8");
    } finally {
        dis.close();
    }
}

16

जावा 7 के साथ, यह UTF-8 फ़ाइल पढ़ने के लिए मेरा पसंदीदा विकल्प है:

String content = new String(Files.readAllBytes(Paths.get(filename)), "UTF-8");

जावा 7 के बाद से, JDK में नया java.nio.fileएपीआई है, जो कई शॉर्टकट प्रदान करता है, इसलिए साधारण फ़ाइल संचालन के लिए 3 पार्टी लाइब्रेरी की हमेशा आवश्यकता नहीं होती है।


15

जावा सभी में सामान्य और लचीला होने का प्रयास करता है। नतीजतन, कुछ जो एक पटकथा भाषा में अपेक्षाकृत सरल है (आपका कोड open(file).read()अजगर में " " के साथ बदल दिया जाएगा ) बहुत अधिक जटिल है। बाहरी पुस्तकालय (जैसे विली गुदा रोहर का उल्लेख है) का उपयोग करने के अलावा, ऐसा करने का कोई छोटा तरीका नहीं लगता है । आपके विकल्प:

  • बाहरी पुस्तकालय का उपयोग करें।
  • इस कोड को अपनी सभी परियोजनाओं में कॉपी करें।
  • अपनी खुद की मिनी-लाइब्रेरी बनाएं जिसमें आपके द्वारा अक्सर उपयोग किए जाने वाले कार्य शामिल हैं।

आपकी सबसे अच्छी शर्त शायद दूसरा है, क्योंकि इसमें सबसे कम निर्भरता है।


4
यीप। यह "उच्च" स्तर की भाषा को एक अलग अर्थ देता है। जावा उच्च स्तर पर सी के साथ तुलना में कम है, लेकिन पायथन या रूबी की तुलना में
OscarRyz

3
सहमत हूँ कि जावा उच्च-स्तरीय अमूर्त पर लंबा है, लेकिन सुविधा के तरीकों पर छोटा है
डोनाल

3
सच है, जावा के पास फ़ाइलों से निपटने के तरीकों की एक पागल संख्या है और उनमें से कई जटिल लगते हैं। लेकिन यह उच्च स्तर की भाषाओं में हमारे पास काफी करीब है:byte[] bytes = Files.readAllBytes(someFile.toPath());
कांटा

11

JDK 8 या इसके बाद के संस्करण का उपयोग करना:

कोई बाहरी पुस्तकालयों का इस्तेमाल नहीं किया

आप फ़ाइल सामग्री ( java.nio.fileपैकेज से कक्षाओं का उपयोग करके ) से एक नई स्ट्रिंग ऑब्जेक्ट बना सकते हैं :

public String readStringFromFile(String filePath) throws IOException {
    String fileContent = new String(Files.readAllBytes(Paths.get(filePath)));
    return fileContent;
}

मोरिट्ज़ पीटरसन के जवाब का डुप्लिकेट जिसने लिखा है: स्ट्रिंग सामग्री = नया स्ट्रिंग (Files.readAllBytes (Paths.get (फ़ाइल नाम)), "UTF-8");
जीन-क्रिस्टोफ ब्लांचर्ड

8

लाइन चर के दायरे को सीमित करने के लिए, लूप के बजाय लूप के लिए उपयोग करने वाले समान थीम पर भिन्नता है। क्या यह "बेहतर" व्यक्तिगत स्वाद की बात है।

for(String line = reader.readLine(); line != null; line = reader.readLine()) {
    stringBuilder.append(line);
    stringBuilder.append(ls);
}

3
यह नई कथनों को डिफ़ॉल्ट न्यूलाइन चॉइस में बदल देगा। यह वांछनीय, या अनपेक्षित हो सकता है।
पीटर लॉरी

इस उत्तर को संपादित करने के लिए वापस लुढ़का क्योंकि बिंदु lineचर के दायरे को कम करना था । संपादन ने इसे दो बार घोषित किया, जो एक संकलन त्रुटि होगी।
डैन डायर

7

यदि आपके पास Filesकक्षा तक पहुंच नहीं है , तो आप एक देशी समाधान का उपयोग कर सकते हैं।

static String readFile(File file, String charset)
        throws IOException
{
    FileInputStream fileInputStream = new FileInputStream(file);
    byte[] buffer = new byte[fileInputStream.available()];
    int length = fileInputStream.read(buffer);
    fileInputStream.close();
    return new String(buffer, 0, length, charset);
}

उदाहरण के लिए आह्वान करने के लिए?
थुफ़ीर

4

एक लचीला समाधान का उपयोग कर IOUtils अपाचे से कॉमन्स-कब के साथ संयोजन में StringWriter :

Reader input = new FileReader();
StringWriter output = new StringWriter();
try {
  IOUtils.copy(input, output);
} finally {
  input.close();
}
String fileContents = output.toString();

यह किसी भी पाठक या इनपुट स्ट्रीम (केवल फाइलों के साथ नहीं) के साथ काम करता है, उदाहरण के लिए जब एक URL से पढ़ता है।


3

ध्यान रखें कि जब fileInputStream.available()लौटे पूर्णांक का उपयोग करना है तो वास्तविक फ़ाइल आकार का प्रतिनिधित्व नहीं करना है, बल्कि बाइट्स की अनुमानित मात्रा को सिस्टम को IO को अवरुद्ध किए बिना स्ट्रीम से पढ़ने में सक्षम होना चाहिए। एक सुरक्षित और सरल तरीका इस तरह दिख सकता है

public String readStringFromInputStream(FileInputStream fileInputStream) {
    StringBuffer stringBuffer = new StringBuffer();
    try {
        byte[] buffer;
        while (fileInputStream.available() > 0) {
            buffer = new byte[fileInputStream.available()];
            fileInputStream.read(buffer);
            stringBuffer.append(new String(buffer, "ISO-8859-1"));
        }
    } catch (FileNotFoundException e) {
    } catch (IOException e) { }
    return stringBuffer.toString();
}

यह माना जाना चाहिए कि यह दृष्टिकोण UTF-8 जैसे बहु-बाइट चरित्र एन्कोडिंग के लिए उपयुक्त नहीं है


1
यह कोड अप्रत्याशित परिणाम दे सकता है। विधि के प्रलेखन के अनुसार available(), इस बात की कोई गारंटी नहीं है कि फ़ाइल का अंत उस स्थिति में हो जाता है कि विधि 0. वापस आ जाती है। उस स्थिति में आप एक अधूरी फ़ाइल के साथ समाप्त हो सकते हैं। क्या बुरा है, वास्तव में पढ़ने वाले बाइट्स की संख्या उस मूल्य से कम हो सकती है available(), जिस स्थिति में आपको दूषित आउटपुट मिलता है।
वाऊ

3

यह एक विधि का उपयोग करता है RandomAccessFile.readFully, यह JDK 1.0 से उपलब्ध लगता है!

public static String readFileContent(String filename, Charset charset) throws IOException {
    RandomAccessFile raf = null;
    try {
        raf = new RandomAccessFile(filename, "r");
        byte[] buffer = new byte[(int)raf.length()];
        raf.readFully(buffer);
        return new String(buffer, charset);
    } finally {
        closeStream(raf);
    }
} 


private static void closeStream(Closeable c) {
    if (c != null) {
        try {
            c.close();
        } catch (IOException ex) {
            // do nothing
        }
    }
}

3

आप स्कैनर और फ़ाइल वर्ग, कुछ लाइनों के समाधान की कोशिश कर सकते हैं

 try
{
  String content = new Scanner(new File("file.txt")).useDelimiter("\\Z").next();
  System.out.println(content);
}
catch(FileNotFoundException e)
{
  System.out.println("not found!");
}

3

java.nio.Filesफ़ाइल की सभी पंक्तियों को पढ़ने के लिए उपयोगकर्ता ।

public String readFile() throws IOException {
        File fileToRead = new File("file path");
        List<String> fileLines = Files.readAllLines(fileToRead.toPath());
        return StringUtils.join(fileLines, StringUtils.EMPTY);
}

3
public static String slurp (final File file)
throws IOException {
    StringBuilder result = new StringBuilder();

    BufferedReader reader = new BufferedReader(new FileReader(file));

    try {
        char[] buf = new char[1024];

        int r = 0;

        while ((r = reader.read(buf)) != -1) {
            result.append(buf, 0, r);
        }
    }
    finally {
        reader.close();
    }

    return result.toString();
}

मुझे लगता है कि प्लेटफ़ॉर्म डिफ़ॉल्ट एन्कोडिंग का उपयोग करने में यह असुविधा ओएस है। +1 फिर भी :)
ऑस्कर रेज़

7
मुझे लगता है कि अंततः ब्लॉक को ब्लॉक में परिभाषित चर नहीं पता है। javac 1.6.0_21 त्रुटि फेंकता है cannot find symbol
ceving

क्या आपने अपना कोड भी आज़माया है? आपने रीडर को कोशिश / पकड़ ब्लॉक में परिभाषित किया है, इसलिए यह अंततः ब्लॉक में सुलभ नहीं होगा।
मौरोन85

2

मैं अभी तक अन्य प्रविष्टियों पर टिप्पणी नहीं कर सकता, इसलिए मैं इसे यहां छोड़ दूंगा।

यहाँ सबसे अच्छे उत्तरों में से एक ( https://stackoverflow.com/a/326448/1521167 ):

private String readFile(String pathname) throws IOException {

File file = new File(pathname);
StringBuilder fileContents = new StringBuilder((int)file.length());
Scanner scanner = new Scanner(file);
String lineSeparator = System.getProperty("line.separator");

try {
    while(scanner.hasNextLine()) {        
        fileContents.append(scanner.nextLine() + lineSeparator);
    }
    return fileContents.toString();
} finally {
    scanner.close();
}
}

अभी भी एक दोष है। यह हमेशा स्ट्रिंग के अंत में नई लाइन चार डालता है, जिससे कुछ अजीब कीड़े हो सकते हैं। मेरा सुझाव इसे बदलना है:

    private String readFile(String pathname) throws IOException {
    File file = new File(pathname);
    StringBuilder fileContents = new StringBuilder((int) file.length());
    Scanner scanner = new Scanner(new BufferedReader(new FileReader(file)));
    String lineSeparator = System.getProperty("line.separator");

    try {
        if (scanner.hasNextLine()) {
            fileContents.append(scanner.nextLine());
        }
        while (scanner.hasNextLine()) {
            fileContents.append(lineSeparator + scanner.nextLine());
        }
        return fileContents.toString();
    } finally {
        scanner.close();
    }
}

पहले मामले में आप अंत में एक अतिरिक्त नई पंक्ति जोड़ सकते हैं। दूसरे मामले में आप एक को छोड़ सकते हैं। इसलिए दोनों समान रूप से गलत हैं। इस लेख को
पैट्रिक पार्कर

2

स्कैनर के बाद Ctrl + F'ing के बाद, मुझे लगता है कि स्कैनर समाधान को भी सूचीबद्ध किया जाना चाहिए। सबसे आसान फैशन पढ़ने के लिए यह इस प्रकार है:

public String fileToString(File file, Charset charset) {
  Scanner fileReader = new Scanner(file, charset);
  fileReader.useDelimiter("\\Z"); // \Z means EOF.
  String out = fileReader.next();
  fileReader.close();
  return out;
}

यदि आप जावा 7 या नए का उपयोग करते हैं (और आपको वास्तव में चाहिए) कोड को पढ़ने में आसान बनाने के लिए कोशिश-के-संसाधनों का उपयोग करने पर विचार करें। कोई और अधिक डॉट-बंद सामान सब कुछ नहीं। लेकिन वह ज्यादातर एक शैलीगत पसंद है।

मैं इसे ज्यादातर पूर्णता के लिए पोस्ट कर रहा हूं, क्योंकि अगर आपको यह करने की आवश्यकता है, तो java.nio.ile.ile में चीजें होनी चाहिए। होनी चाहिए जो काम को बेहतर तरीके से करना चाहिए।

मेरा सुझाव सभी बाइट्स को हथियाने के लिए # readAllBytes (पाथ) का उपयोग करना होगा , और इसे नई स्ट्रिंग (बाइट [] चारसेट) को फीड करना होगा। से प्राप्त करने के पर होगा, जिस पर आप भरोसा कर सकते हैं। आपके जीवनकाल में चारसेट आपके लिए होगा, इसलिए अब इस सामान से सावधान रहें।

दूसरों ने कोड और सामान दिया है, और मैं उनकी महिमा चोरी नहीं करना चाहता। ;)



2

अगर आपकी फ़ाइल जार के अंदर है, तो भी आप इसका उपयोग कर सकते हैं:

public String fromFileInJar(String path) {
    try ( Scanner scanner 
            = new Scanner(getClass().getResourceAsStream(path))) {
        return scanner.useDelimiter("\\A").next();
    }
}

/ अगर आपका जार है तो रास्ते को उदाहरण के लिए शुरू करना चाहिए

my.jar/com/some/thing/a.txt

फिर आप इसे इस तरह से लागू करना चाहते हैं:

String myTxt = fromFileInJar("/com/com/thing/a.txt");


2

@ Erickson`s जवाब के आधार पर, आप उपयोग कर सकते हैं:

public String readAll(String fileName) throws IOException {
    List<String> lines = Files.readAllLines(new File(fileName).toPath());
    return String.join("\n", lines.toArray(new String[lines.size()]));
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.