सवाल स्ट्रिंग में इनपुटस्ट्रीम को पढ़ें / कनवर्ट करें


अगर आपके पास एक है java.io.InputStream ऑब्जेक्ट, आपको उस ऑब्जेक्ट को कैसे संसाधित करना चाहिए और एक उत्पादन करना चाहिए String?


मान लीजिए मेरे पास एक है InputStream जिसमें टेक्स्ट डेटा है, और मैं इसे एक में परिवर्तित करना चाहता हूं String, इसलिए उदाहरण के लिए मैं इसे एक लॉग फ़ाइल में लिख सकता हूं।

लेने का सबसे आसान तरीका क्या है InputStream और इसे एक में परिवर्तित करें String?

public String convertStreamToString(InputStream is) { 
    // ???
}

3267
2017-11-21 16:47


मूल


लड़का, मैं पूरी तरह से जावा के साथ प्यार करता हूं, लेकिन यह सवाल इतनी बार आता है कि आपको लगता है कि वे केवल यह समझ लेंगे कि धाराओं की श्रृंखला कुछ हद तक मुश्किल है और या तो विभिन्न संयोजन बनाने या पूरी चीज पर पुनर्विचार करने में मददगार बनाते हैं। - Bill K
इस प्रश्न का उत्तर केवल तभी काम करता है जब आप स्ट्रीम की सामग्री को पढ़ना चाहते हैं पूरी तरह से (जब तक यह बंद नहीं हो जाता है)। चूंकि इसका हमेशा इरादा नहीं है (एक जीवित कनेक्शन के साथ http अनुरोध बंद नहीं होंगे), ये विधि ब्लॉक (आपको सामग्री नहीं दे रही हैं) कहते हैं। - f1sh
आप जरुरत स्ट्रीम के लिए वर्ण एन्कोडिंग को जानने और निर्दिष्ट करने के लिए, या आप मर्जी चरित्र एन्कोडिंग बग है, क्योंकि आप उस मशीन / ऑपरेटिंग सिस्टम / प्लेटफॉर्म या उसके कोड का संस्करण चालू होने के आधार पर यादृच्छिक रूप से चुने गए एन्कोडिंग का उपयोग करेंगे। वह है, करो नहीं प्लेटफ़ॉर्म डिफ़ॉल्ट एन्कोडिंग पर निर्भर विधियों का उपयोग करें। - Christoffer Hammarström
9 साल पहले से अपनी खुद की टिप्पणी के साथ मजा करने के लिए, इन दिनों मैं ग्रोवी की "स्ट्रिंग एस = नई फाइल (" SomeFile.txt ") का उपयोग करता हूं। पाठ" एक पूरी फाइल को एक बार में पढ़ने के लिए और यह बहुत अच्छा काम करता है। मैं अपने गैर-उत्पादन (स्क्रिप्टिंग) कोड के लिए ग्रोवी का उपयोग करने से खुश हूं और - ईमानदारी से आपको एन्कोडिंग से निपटने के लिए मजबूर कर रहा हूं और जावा की तरह बहुत लंबी फाइलें उत्पादन कोड के लिए वास्तव में एक अच्छा विचार है, इसलिए यह इसके उद्देश्य के लिए काम करती है, ग्रोवी त्वरित लिपियों के लिए काम करता है जो जावा महान नहीं है - बस नौकरी के लिए सही उपकरण का उपयोग करें और यह सब काम करता है। - Bill K
बस सरलीकृत करना: ByteArrayOutputStream outputBytes = new ByteArrayOutputStream();  for(byte[] b = new byte[512]; 0 < inputStream.read(b); outputBytes.write(b));  return new String(outputBytes.toByteArray(), StandardCharsets.UTF_8); - Felypp Oliveira


जवाब:


ऐसा करने का एक अच्छा तरीका उपयोग कर रहा है अपाचे कॉमन्स  IOUtils कॉपी करने के लिए InputStream में StringWriter... कुछ इस तरह

StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer, encoding);
String theString = writer.toString();

या और भी

// NB: does not close inputStream, you'll have to use try-with-resources for that
String theString = IOUtils.toString(inputStream, encoding); 

वैकल्पिक रूप से, आप उपयोग कर सकते हैं ByteArrayOutputStream यदि आप अपने स्ट्रीम और लेखकों को मिश्रण नहीं करना चाहते हैं


2048
2017-11-21 16:54



मुझे filenotfound अपवाद मिला, जबकि मैं "До_свидания" फ़ाइल नाम (रूसी भाषा) के साथ फ़ाइल नाम पढ़ने की कोशिश करता हूं, मैं FileInputstream के साथ प्रयास करता हूं लेकिन यह sdcard से इस फ़ाइल नाम को पढ़ने के लिए केबल नहीं है। - Bhanu Sharma
एंड्रॉइड डेवलपर्स के लिए, ऐसा लगता है जैसे एंड्रॉइड Iache के साथ Apache से नहीं आता है। तो आप अन्य उत्तरों का जिक्र करने पर विचार कर सकते हैं। - Chris.Zou
मैं एक सीमित पदचिह्न पर्यावरण में काम करता हूं, इसलिए जावा io / उपयोग libs का उपयोग करके नीचे @PavelRepin द्वारा समाधान अधिक समझ में आता है। - James
इस बिंदु पर यह एक अविश्वसनीय रूप से पुराना सवाल है (इसे 2008 में पूछा गया था)। अधिक आधुनिक उत्तरों के माध्यम से पढ़ने के लिए आपके समय के लायक है। कुछ जावा 8 लाइब्रेरी से देशी कॉल का उपयोग करते हैं। - Shadoninja
यह उत्तर बहुत पुराना है और इसे इस तरह चिह्नित करने में सक्षम होना चाहिए (दुख की बात यह संभव नहीं है)। - codepleb


यहां केवल मानक जावा लाइब्रेरी का उपयोग करने का एक तरीका है (ध्यान दें कि स्ट्रीम बंद नहीं है, वाईएमएमवी)।

static String convertStreamToString(java.io.InputStream is) {
    java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
    return s.hasNext() ? s.next() : "";
}

मैंने इस चाल को सीखा "बेवकूफ स्कैनर चालें" लेख। इसका कारण यह है क्योंकि स्कैनर धारा में टोकन पर पुनरावृत्त होता है, और इस मामले में हम "इनपुट सीमा की शुरुआत" (\ ए) का उपयोग करके टोकन को अलग करते हैं, इस प्रकार हम स्ट्रीम की पूरी सामग्री के लिए केवल एक टोकन देते हैं।

नोट, यदि आपको इनपुट स्ट्रीम के एन्कोडिंग के बारे में विशिष्ट होना आवश्यक है, तो आप दूसरा तर्क प्रदान कर सकते हैं Scanner निर्माता जो इंगित करता है कि किस वर्ण का उपयोग करना है (उदा। "यूटीएफ -8")।

हैट टिप भी जाता है याकूब, जिसने मुझे एक बार लेख में इंगित किया।

संपादित: से एक सुझाव के लिए धन्यवाद पैट्रिक, खाली इनपुट स्ट्रीम को संभालने पर फ़ंक्शन को और अधिक मजबूत बना दिया। एक और संपादन: मिश्रित कोशिश / पकड़, पैट्रिक का रास्ता अधिक लापरवाही है।


2093
2018-03-26 20:40



धन्यवाद, इसके मेरे संस्करण के लिए मैंने आखिरकार ब्लॉक जोड़ा जो इनपुट स्ट्रीम को बंद कर देता है, इसलिए उपयोगकर्ता को इनपुट पढ़ने को समाप्त करने के बाद से ऐसा नहीं करना पड़ता है। कॉलर कोड को काफी सरल बनाता है।
@PavelRepin @ पैट्रिक मेरे मामले में, एक खाली इनपुटस्ट्रीम ने स्कैनर निर्माण के दौरान एक एनपीई का कारण बना दिया। मुझे जोड़ना पड़ा if (is == null) return ""; विधि की शुरुआत में सही; मेरा मानना ​​है कि इस जवाब को नल इनपुटस्ट्रीम को बेहतर तरीके से संभालने के लिए अद्यतन करने की आवश्यकता है। - CFL_Jeff
जावा 7 के लिए आप एक कोशिश में बंद कर सकते हैं: try(java.util.Scanner s = new java.util.Scanner(is)) { return s.useDelimiter("\\A").hasNext() ? s.next() : ""; } - earcam
दुर्भाग्य से यह समाधान मेरे अंतर्निहित धारा कार्यान्वयन में फेंकने वाले अपवादों को खो देता है और खो देता है। - Taig
FYI करें, hasNext कंसोल इनपुट धाराओं पर ब्लॉक (देखें यहाँ)। (अभी इस मुद्दे में अभी भाग गया है।) यह समाधान अन्यथा ठीक काम करता है ... बस एक सिर ऊपर। - Ryan


अन्य उत्तरों का संक्षेप में मुझे यह करने के 11 मुख्य तरीके मिले (नीचे देखें)। और मैंने कुछ प्रदर्शन परीक्षण लिखे (नीचे परिणाम देखें):

किसी इनपुटस्ट्रीम को स्ट्रिंग में कनवर्ट करने के तरीके:

  1. का उपयोग करते हुए IOUtils.toString (अपाचे उपयोग)

    String result = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
    
  2. का उपयोग करते हुए CharStreams (अमरूद)

    String result = CharStreams.toString(new InputStreamReader(
          inputStream, Charsets.UTF_8));
    
  3. का उपयोग करते हुए Scanner (JDK)

    Scanner s = new Scanner(inputStream).useDelimiter("\\A");
    String result = s.hasNext() ? s.next() : "";
    
  4. का उपयोग करते हुए स्ट्रीम एपीआई (जावा 8)। चेतावनी: यह समाधान विभिन्न लाइन ब्रेक (जैसे \r\n) सेवा मेरे \n

    String result = new BufferedReader(new InputStreamReader(inputStream))
      .lines().collect(Collectors.joining("\n"));
    
  5. का उपयोग करते हुए समांतर स्ट्रीम एपीआई (जावा 8)। चेतावनी: यह समाधान विभिन्न लाइन ब्रेक (जैसे \r\n) सेवा मेरे \n

    String result = new BufferedReader(new InputStreamReader(inputStream)).lines()
       .parallel().collect(Collectors.joining("\n"));
    
  6. का उपयोग करते हुए InputStreamReader तथा StringBuilder (JDK)

    final int bufferSize = 1024;
    final char[] buffer = new char[bufferSize];
    final StringBuilder out = new StringBuilder();
    Reader in = new InputStreamReader(inputStream, "UTF-8");
    for (; ; ) {
        int rsz = in.read(buffer, 0, buffer.length);
        if (rsz < 0)
            break;
        out.append(buffer, 0, rsz);
    }
    return out.toString();
    
  7. का उपयोग करते हुए StringWriter तथा IOUtils.copy (अपाचे कॉमन्स)

    StringWriter writer = new StringWriter();
    IOUtils.copy(inputStream, writer, "UTF-8");
    return writer.toString();
    
  8. का उपयोग करते हुए ByteArrayOutputStream तथा inputStream.read (JDK)

    ByteArrayOutputStream result = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream.read(buffer)) != -1) {
        result.write(buffer, 0, length);
    }
    // StandardCharsets.UTF_8.name() > JDK 7
    return result.toString("UTF-8");
    
  9. का उपयोग करते हुए BufferedReader (JDK)। चेतावनी: यह समाधान विभिन्न लाइन ब्रेक (जैसे \n\r) सेवा मेरे line.separator सिस्टम प्रॉपर्टी (उदाहरण के लिए, विंडोज़ में "\ r \ n")।

    String newLine = System.getProperty("line.separator");
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    StringBuilder result = new StringBuilder();
    String line; boolean flag = false;
    while ((line = reader.readLine()) != null) {
        result.append(flag? newLine: "").append(line);
        flag = true;
    }
    return result.toString();
    
  10. का उपयोग करते हुए BufferedInputStream तथा ByteArrayOutputStream (JDK)

    BufferedInputStream bis = new BufferedInputStream(inputStream);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    int result = bis.read();
    while(result != -1) {
        buf.write((byte) result);
        result = bis.read();
    }
    // StandardCharsets.UTF_8.name() > JDK 7
    return buf.toString("UTF-8");
    
  11. का उपयोग करते हुए inputStream.read() तथा StringBuilder (JDK)। चेतावनी: इस समाधान में यूनिकोड के साथ समस्याएं हैं, उदाहरण के लिए रूसी पाठ के साथ (केवल गैर-यूनिकोड टेक्स्ट के साथ सही ढंग से काम करता है)

    int ch;
    StringBuilder sb = new StringBuilder();
    while((ch = inputStream.read()) != -1)
        sb.append((char)ch);
    reset();
    return sb.toString();
    

चेतावनी:

  1. समाधान 4, 5 और 9 अलग-अलग लाइन ब्रेक को एक में परिवर्तित करते हैं।

  2. समाधान 11 यूनिकोड टेक्स्ट के साथ सही ढंग से काम नहीं कर सकता है

प्रदर्शन जांच

छोटे के लिए प्रदर्शन परीक्षण String (लंबाई = 175), यूआरएल में GitHub (मोड = औसत समय, सिस्टम = लिनक्स, स्कोर 1,343 सबसे अच्छा है):

              Benchmark                         Mode  Cnt   Score   Error  Units
 8. ByteArrayOutputStream and read (JDK)        avgt   10   1,343 ± 0,028  us/op
 6. InputStreamReader and StringBuilder (JDK)   avgt   10   6,980 ± 0,404  us/op
10. BufferedInputStream, ByteArrayOutputStream  avgt   10   7,437 ± 0,735  us/op
11. InputStream.read() and StringBuilder (JDK)  avgt   10   8,977 ± 0,328  us/op
 7. StringWriter and IOUtils.copy (Apache)      avgt   10  10,613 ± 0,599  us/op
 1. IOUtils.toString (Apache Utils)             avgt   10  10,605 ± 0,527  us/op
 3. Scanner (JDK)                               avgt   10  12,083 ± 0,293  us/op
 2. CharStreams (guava)                         avgt   10  12,999 ± 0,514  us/op
 4. Stream Api (Java 8)                         avgt   10  15,811 ± 0,605  us/op
 9. BufferedReader (JDK)                        avgt   10  16,038 ± 0,711  us/op
 5. parallel Stream Api (Java 8)                avgt   10  21,544 ± 0,583  us/op

बड़े के लिए प्रदर्शन परीक्षण String (लंबाई = 50100), यूआरएल में GitHub (मोड = औसत समय, सिस्टम = लिनक्स, स्कोर 200,715 सर्वश्रेष्ठ है):

               Benchmark                        Mode  Cnt   Score        Error  Units
 8. ByteArrayOutputStream and read (JDK)        avgt   10   200,715 ±   18,103  us/op
 1. IOUtils.toString (Apache Utils)             avgt   10   300,019 ±    8,751  us/op
 6. InputStreamReader and StringBuilder (JDK)   avgt   10   347,616 ±  130,348  us/op
 7. StringWriter and IOUtils.copy (Apache)      avgt   10   352,791 ±  105,337  us/op
 2. CharStreams (guava)                         avgt   10   420,137 ±   59,877  us/op
 9. BufferedReader (JDK)                        avgt   10   632,028 ±   17,002  us/op
 5. parallel Stream Api (Java 8)                avgt   10   662,999 ±   46,199  us/op
 4. Stream Api (Java 8)                         avgt   10   701,269 ±   82,296  us/op
10. BufferedInputStream, ByteArrayOutputStream  avgt   10   740,837 ±    5,613  us/op
 3. Scanner (JDK)                               avgt   10   751,417 ±   62,026  us/op
11. InputStream.read() and StringBuilder (JDK)  avgt   10  2919,350 ± 1101,942  us/op

ग्राफ (विंडोज 7 सिस्टम में इनपुट स्ट्रीम लंबाई के आधार पर प्रदर्शन परीक्षण)
enter image description here

विंडोज 7 सिस्टम में इनपुट स्ट्रीम लंबाई के आधार पर प्रदर्शन परीक्षण (औसत समय):

 length  182    546     1092    3276    9828    29484   58968

 test8  0.38    0.938   1.868   4.448   13.412  36.459  72.708
 test4  2.362   3.609   5.573   12.769  40.74   81.415  159.864
 test5  3.881   5.075   6.904   14.123  50.258  129.937 166.162
 test9  2.237   3.493   5.422   11.977  45.98   89.336  177.39
 test6  1.261   2.12    4.38    10.698  31.821  86.106  186.636
 test7  1.601   2.391   3.646   8.367   38.196  110.221 211.016
 test1  1.529   2.381   3.527   8.411   40.551  105.16  212.573
 test3  3.035   3.934   8.606   20.858  61.571  118.744 235.428
 test2  3.136   6.238   10.508  33.48   43.532  118.044 239.481
 test10 1.593   4.736   7.527   20.557  59.856  162.907 323.147
 test11 3.913   11.506  23.26   68.644  207.591 600.444 1211.545

1656
2018-02-17 00:58



जैसा कि आप "सारांश उत्तर" लिख रहे हैं, आपको ध्यान रखना चाहिए कि कुछ समाधान स्वचालित रूप से विभिन्न लाइनब्रैक (जैसे \r\n) सेवा मेरे \n जो कुछ मामलों में अवांछित हो सकता है। इसके अलावा अतिरिक्त मेमोरी या कम से कम आवंटन दबाव देखना अच्छा लगेगा (कम से कम आप जेएमएच को चला सकते हैं -prof gc)। वास्तव में कूल पोस्ट के लिए ग्राफ देखना बहुत अच्छा होगा (उसी इनपुट आकार के भीतर स्ट्रिंग लम्बाई के आधार पर और उसी स्ट्रिंग लम्बाई के भीतर इनपुट आकार के आधार पर)। - Tagir Valeev
upvoted; सबसे मजेदार बात यह है कि परिणाम अपेक्षा से अधिक हैं: किसी को मानक जेडीके और / या अपाचे कॉमन्स सिंटैक्टिक चीनी का उपयोग करना चाहिए। - mudasobwa
अद्भुत पोस्ट बस एक बात। जावा 8 उन संसाधनों पर समांतर धाराओं का उपयोग करने के खिलाफ चेतावनी देता है जो आपको लॉक करने और प्रतीक्षा करने के लिए मजबूर करेंगे (जैसे कि यह इनपुट स्ट्रीम) ताकि समांतर स्ट्रीम विकल्प बल्कि बोझिल हो और इसके लायक नहीं हो? - mangusbrother
समानांतर धारा वास्तव में लाइन ऑर्डरिंग को बनाए रखती है? - Natix
क्या है reset() उदाहरण के लिए 11? - Rob Stewart


अपाचे कॉमन्स अनुमति देता है:

String myString = IOUtils.toString(myInputStream, "UTF-8");

बेशक, आप यूटीएफ -8 के अलावा अन्य चरित्र एन्कोडिंग चुन सकते हैं।

और देखें: (डॉक्स)


794
2017-12-08 20:13



साथ ही, एक विधि है जो केवल इनपुटस्ट्रीम तर्क लेती है, यदि आप डिफ़ॉल्ट एन्कोडिंग के साथ पा रहे हैं। - Guillaume Coté
@ गुइलाउम कोटे मुझे लगता है कि यहां संदेश यह है कि आपको कभी भी "डिफ़ॉल्ट एन्कोडिंग के साथ ठीक" नहीं होना चाहिए, क्योंकि आप यह सुनिश्चित नहीं कर सकते कि जावा कोड चलने वाले मंच के आधार पर आप क्या कर सकते हैं। - Per Wiklander
@Per विकलैंडर मैं आपसे असहमत हूं। कोड जो एकल पर काम करने जा रहा है, यह सुनिश्चित हो सकता है कि डिफ़ॉल्ट एन्कोडिंग ठीक रहेगी। कोड के लिए जो केवल स्थानीय फ़ाइल खोलता है, प्लेटफ़ॉर्म डिफ़ॉल्ट एन्कोडिंग में एन्कोड किए जाने के लिए यह एक उचित विकल्प है। - Guillaume Coté
किसी को भी गुगलिंग की परेशानी बचाने के लिए - <निर्भरता> <groupId> org.apache.commons </ groupId> <artifactId> commons-io </ artifactId> <version> 1.3.2 </ version> </ निर्भरता> - Chris
सादा स्ट्रिंग शाब्दिक का उपयोग करने के बजाय वर्ण एन्कोडिंग के लिए अपाचे io (या अन्य) निरंतर उपयोग करने के लिए भी थोड़ा सुधार होगा - उदाहरण: IOUtils.toString (myInputStream, Charsets.UTF_8);


खाता फ़ाइल में लेना सबसे पहले एक प्राप्त करना चाहिए java.io.Reader उदाहरण। इसे तब पढ़ा और जोड़ा जा सकता है StringBuilder (हमें जरूरत नहीं है StringBuffer अगर हम इसे एकाधिक धागे में नहीं पहुंच रहे हैं, और StringBuilder ज्यादा तेज़ है)। यहां चाल यह है कि हम ब्लॉक में काम करते हैं, और इस तरह अन्य बफरिंग धाराओं की आवश्यकता नहीं होती है। ब्लॉक आकार को रन-टाइम प्रदर्शन अनुकूलन के लिए पैरामीटर किया गया है।

public static String slurp(final InputStream is, final int bufferSize) {
    final char[] buffer = new char[bufferSize];
    final StringBuilder out = new StringBuilder();
    try (Reader in = new InputStreamReader(is, "UTF-8")) {
        for (;;) {
            int rsz = in.read(buffer, 0, buffer.length);
            if (rsz < 0)
                break;
            out.append(buffer, 0, rsz);
        }
    }
    catch (UnsupportedEncodingException ex) {
        /* ... */
    }
    catch (IOException ex) {
        /* ... */
    }
    return out.toString();
}

263
2017-08-04 08:29



यह समाधान मल्टीबाइट वर्णों का उपयोग करता है। उदाहरण यूटीएफ -8 एन्कोडिंग का उपयोग करता है जो पूर्ण यूनिकोड रेंज (चीनी सहित) की अभिव्यक्ति की अनुमति देता है। एक और एन्कोडिंग के साथ "यूटीएफ -8" को प्रतिस्थापित करने से एन्कोडिंग का उपयोग किया जा सकेगा। - Paul de Vrieze
@ उपयोगकर्ता 1 - मुझे अपने कोड में पुस्तकालयों का उपयोग करना पसंद है, इसलिए मैं अपना काम तेजी से कर सकता हूं। यह बहुत ही बढ़िया है जब आपके प्रबंधक कहते हैं "वाह जेम्स! तुमने इतनी तेजी से ऐसा कैसे किया ?!"। लेकिन जब हमें पहिया को फिर से शुरू करने में समय बिताना पड़ता है क्योंकि हमने एक आम, पुन: प्रयोज्य, कोशिश की और परीक्षण की उपयोगिता के बारे में विचारों को गलत तरीके से खो दिया है, तो हम समय छोड़ रहे हैं कि हम अपने प्रोजेक्ट के लक्ष्यों को आगे बढ़ाने में खर्च कर सकते हैं। जब हम पहिया को फिर से शुरू करते हैं, तो हम दो बार कड़ी मेहनत करते हैं, फिर भी बाद में फिनिश लाइन तक पहुंच जाते हैं। एक बार जब हम फिनिश लाइन पर हों, तो हमें बधाई देने के लिए कोई भी नहीं है। घर बनाने के दौरान, हथौड़ा भी न बनाएं - jmort253
क्षमा करें, मेरी टिप्पणी दोबारा पढ़ने के बाद, यह थोड़ा अहंकार से आता है। मुझे लगता है कि पुस्तकालयों से बचने के लिए एक अच्छा कारण होना महत्वपूर्ण है और यह कारण एक वैध है, जो बहुत अच्छा हो सकता है :) - jmort253
@ jmort253 हमने कई बार हमारे उत्पाद में कुछ लाइब्रेरी अपडेट करने के बाद प्रदर्शन प्रतिगमन देखा। सौभाग्य से हम अपने खुद के उत्पाद का निर्माण और बिक्री कर रहे हैं, इसलिए हमारे पास वास्तव में तथाकथित समय सीमा नहीं है। दुर्भाग्यवश हम एक ऐसे उत्पाद का निर्माण कर रहे हैं जो कई ऑपरेशन सिस्टम पर कई जेवीएम, डेटाबेस और ऐप सर्वर पर उपलब्ध है, इसलिए हमें खराब मशीनों का उपयोग करने वाले उपयोगकर्ताओं के बारे में सोचना होगा ... और एक स्ट्रिंग ऑपरेशन ऑप्टिमाइज़िंग 30 ~ 40% तक पेर्फ को बेहतर बना सकती है। और एक फिक्स: In our product, I even replaced होना चाहिए 'हम भी बदल दिया'। - coolcfan
@ jmort253 अगर आप पहले ही अपाचे कॉमन्स का उपयोग करेंगे, तो मैं कहूंगा, इसके लिए जाएं। साथ ही, पुस्तकालयों का उपयोग करने के लिए एक वास्तविक लागत है (कई अपाचे जावा पुस्तकालयों में निर्भरता प्रसार के रूप में)। यदि यह पुस्तकालय का एकमात्र उपयोग होगा, तो लाइब्रेरी का उपयोग करने के लिए यह अधिक होगा। दूसरी तरफ, अपना खुद का बफर आकार निर्धारित करना आप अपनी मेमोरी / प्रोसेसर उपयोग संतुलन को ट्यून कर सकते हैं। - Paul de Vrieze


इस बारे में कैसा है?

InputStream in = / * आपके इनपुटस्ट्रीम * /;
StringBuilder sb=new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String read;

while((read=br.readLine()) != null) {
    //System.out.println(read);
    sb.append(read);   
}

br.close();
return sb.toString();

226
2017-07-13 15:56



बात यह है कि, आप पहले लाइनों में विभाजित हो रहे हैं, और उसके बाद इसे पूर्ववत कर रहे हैं। मनमाने ढंग से बफर पढ़ने के लिए यह आसान और तेज़ है। - Paul de Vrieze
साथ ही, readLine \ n और \ r के बीच अंतर नहीं करता है, इसलिए आप फिर से सटीक स्ट्रीम को पुन: पेश नहीं कर सकते हैं। - María Arias de Reyna Domínguez
@PauldeVrieze कितनी लाइनें, और आपको उन्हें संसाधित करने की कितनी जल्दी आवश्यकता है !? मुझे लगता है कि किसी भी प्रदर्शन की कमी कम होगी, या किसी फ़ाइल में उन्हें लॉग इन करने और पुरानी स्ट्रिंग ओब्जे को नष्ट करने के दौरान हर बार संभाला जा सकता है। - Thufir
बहुत अक्षम, के रूप में readLine ईओएल देखने के लिए चरित्र द्वारा चरित्र पढ़ें। इसके अलावा, अगर स्ट्रीम में कोई लाइन ब्रेक नहीं है, तो यह वास्तव में समझ में नहीं आता है। - njzk2
यह सबसे अच्छा जवाब नहीं है क्योंकि यह बाइट आउट में कड़ाई से बाइट नहीं है। पाठक chlps newlines, तो आप उन्हें बनाए रखने के लिए सावधान रहना होगा। - Jeffrey Blattman


यदि आप Google-संग्रह / अमरूद का उपयोग कर रहे हैं तो आप निम्न कार्य कर सकते हैं:

InputStream stream = ...
String content = CharStreams.toString(new InputStreamReader(stream, Charsets.UTF_8));
Closeables.closeQuietly(stream);

ध्यान दें कि दूसरे पैरामीटर (यानी Charsets.UTF_8) के लिए InputStreamReader जरूरी नहीं है, लेकिन एन्कोडिंग निर्दिष्ट करना आम तौर पर एक अच्छा विचार है यदि आप इसे जानते हैं (जो आपको चाहिए!)


153
2018-05-08 20:24



@ हर्सचवेयर: सवाल यह था कि: "यदि आपके पास java.io.InputStream ऑब्जेक्ट है तो आप उस ऑब्जेक्ट को कैसे संसाधित कर सकते हैं और स्ट्रिंग का उत्पादन कैसे कर सकते हैं?" मैंने माना कि स्थिति में एक धारा पहले से मौजूद है। - Sakuraba
आपने अपने उत्तर को बहुत अच्छी तरह से समझाया नहीं था, और इसमें विविध चर थे; user359996 ने आपके जैसा ही कहा, लेकिन अधिक स्पष्ट रूप से। - Uronym
इनपुट स्ट्रीम के एन्कोडिंग को निर्दिष्ट नहीं करने के लिए guava के लिए +1, -1। जैसे। नया इनपुटस्ट्रीम रीडर (स्ट्रीम, "यूटीएफ -8") - andras
@ क्रिस नोडस दूसरी तरफ, कुछ लोगों के पास पहले से ही उनके प्रोजेक्ट में अमरूद है, और लगता है कि यह समाधान एसडीके-केवल संस्करण की तुलना में अधिक सुरुचिपूर्ण है। - CorayThan
@Vadzim कि उत्तर इस जैसा ही है - दोनों CharStreams.toString का उपयोग करें - Tom


यह मेरा शुद्ध जावा और एंड्रॉइड समाधान है, अच्छी तरह से काम करता है ...

public String readFullyAsString(InputStream inputStream, String encoding)
        throws IOException {
    return readFully(inputStream).toString(encoding);
}    

public byte[] readFullyAsBytes(InputStream inputStream)
        throws IOException {
    return readFully(inputStream).toByteArray();
}    

private ByteArrayOutputStream readFully(InputStream inputStream)
        throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length = 0;
    while ((length = inputStream.read(buffer)) != -1) {
        baos.write(buffer, 0, length);
    }
    return baos;
}

107
2018-06-10 21:07



एंड्रॉइड पर अन्य उत्तरों की तुलना में अच्छी तरह से काम करता है जो केवल एंटरप्राइज़ जावा में काम करता है। - vorrtex
एंड्रॉइड में एंड्रॉइड में क्रैश हो गया, ".write" लाइन पर आउटऑफमेमरी त्रुटि, हर बार, छोटे तारों के लिए। - Adam
मैंने एन्कोडिंग जोड़ा है। एक साइड नोट के रूप में, मेरे कोड में मूल रीडफुल विधि मेरे स्ट्रिंग को वापस नहीं करती है, यह अधिक सामान्य उद्देश्य कार्यक्षमता के लिए बाइट [] देता है। एन्कोडिंग के साथ नई स्ट्रिंग (...) को कार्यान्वित करना एपीआई का उपयोग करने की ज़िम्मेदारी है! - TacB0sS
त्वरित नोट: इसकी स्मृति पदचिह्न अधिकतम है 2*n, जहां एन धारा के आकार के अनुसार है ByteArrayInputStream ऑटो बढ़ती प्रणाली। - njzk2
अनावश्यक रूप से स्मृति उपयोग को दोगुना करता है, यह मोबाइल उपकरणों पर कीमती है। आप इनपुटप्रीम रीडर का बेहतर उपयोग करेंगे और स्ट्रिंग रीडर में संलग्न होंगे, बाइट टू चार रूपांतरण फ्लाई पर किया जाएगा, अंत में थोक में नहीं। - Oliv


कैसा रहेगा:

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;    

public static String readInputStreamAsString(InputStream in) 
    throws IOException {

    BufferedInputStream bis = new BufferedInputStream(in);
    ByteArrayOutputStream buf = new ByteArrayOutputStream();
    int result = bis.read();
    while(result != -1) {
      byte b = (byte)result;
      buf.write(b);
      result = bis.read();
    }        
    return buf.toString();
}

56
2018-01-01 03:43



यह धीमा है, क्योंकि बाइट द्वारा बाइट पढ़ता है। - Daniel De León
@ डैनियल डीलेन नहीं, ऐसा नहीं है। यह है BufferedInputStream। एक समय में अंतर्निहित पढ़ 8192 बाइट हैं। - user207421
@EJP मैंने इसे उपयोग करने से धीमा होने के लिए पाया है BufferedInputStream  तथा एक समय में एक बाइट के बजाय एक बाइट सरणी बफर में पढ़ना। उदाहरण: एक 4.56 एमआईबी फ़ाइल पढ़ने के दौरान 200ms बनाम 60ms। - jk7


यहां कुछ प्रयोग के बाद आया सबसे सुंदर, शुद्ध-जावा (कोई लाइब्रेरी) समाधान नहीं है:

public static String fromStream(InputStream in) throws IOException
{
    BufferedReader reader = new BufferedReader(new InputStreamReader(in));
    StringBuilder out = new StringBuilder();
    String newLine = System.getProperty("line.separator");
    String line;
    while ((line = reader.readLine()) != null) {
        out.append(line);
        out.append(newLine);
    }
    return out.toString();
}

55
2017-09-02 11:50



क्या कोई पाठक नहीं है। () गायब है? आदर्श रूप से कोशिश / आखिरकार ... - Torben Kohlmeier
@ टोरबेन कोहल्मेयर, पाठकों और बफर को बंद करने की आवश्यकता नहीं है। प्रदान किया गया InputStream कॉलर द्वारा बंद किया जाना चाहिए। - Drew Noakes
उल्लेख करना न भूलें कि InputStreamReader में एक अधिक बेहतर कन्स्ट्रक्टर है जो एक CharSet लेता है। - jontejj
लोग क्यों उपयोग करते रहते हैं readLine? यदि आप प्रति पंक्तियों का उपयोग नहीं करते हैं, तो यह कितना अच्छा है (बहुत धीमा होने के अलावा?) - njzk2
@ वोहो, यदि एक पंक्ति लंबी है, तो वापसी मूल्य आवंटित करने का कोई तरीका नहीं है जो कि उस रेखा के आकार में बराबर या अधिक होना चाहिए। यदि आप बड़ी फ़ाइलों से निपट रहे हैं, तो आपको उन्हें स्ट्रीम करना चाहिए। यद्यपि छोटी पाठ फ़ाइलों को स्मृति में लोड करने के लिए बहुत सारे उपयोग मामले हैं। - Drew Noakes


यहां पूर्णता के लिए है जावा 9 उपाय:

public static String toString(InputStream input) throws IOException {
    return new String(input.readAllBytes(), StandardCharsets.UTF_8);
}

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


41
2017-07-17 17:58



क्या विधि पढ़ने के लिए पूरी तरह से स्मृति को आवंटित नहीं करती है? byte[] buf = new byte[DEFAULT_BUFFER_SIZE]; कहा पे MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8; जो देता है MAX_BUFFER_SIZE = 2147483639। Google इसके बारे में 2.147 जीबी कहता है। - Rekin
क्षमा करें, मैंने गणना में एक त्रुटि की है। यह 2 जीबी है। मैंने टिप्पणी संपादित की है। तो, अगर मैं 4kb फ़ाइल की तरह पढ़ता हूं तो भी मैं 2 जीबी मेमोरी का उपयोग करता हूं? - Rekin
@ क्रिस्टियन हूजर, मैं इसे में नहीं देखता हूं नवीनतम jdk8u प्रतिबद्ध। जावा अपडेट में AFAIK नई विधियों को कभी भी पेश नहीं किया जाता है, केवल प्रमुख रिलीज में। - Tagir Valeev
@ क्रिस्टियन हूजर, सवाल था InputStream, के बारे में नहीं Path। InputStream कई अलग-अलग स्रोतों से बनाया जा सकता है, न केवल फाइलें। - Tagir Valeev
यह एक साल पहले लिखा गया था, इसलिए अपडेट करने के लिए, मैं पुष्टि करता हूं कि यह विधि वास्तव में सार्वजनिक रिलीज जेडीके 9 में है। इसके अलावा, यदि आपका एन्कोडिंग "आईएसओ-लैटिन -1" है तो यह जावा 9 स्ट्रिंग्स अब उपयोग के बाद से बेहद कुशल होगा ए byte[] कार्यान्वयन अगर सभी पात्र पहले 256 कोड बिंदुओं में हैं। इसका मतलब है कि नई स्ट्रिंग (बाइट [], "आईएसओ-लैटिन -1") एक साधारण सरणी प्रतिलिपि होगी। - Klitos Kyriacou