एक रीडर को इनपुटस्ट्रीम और एक राइटर को आउटपुटस्ट्रीम में कैसे बदलें?


जवाबों:


45

आप वास्तव में पाठ एन्कोडिंग मुद्दों से निपटने से बच नहीं सकते हैं, लेकिन अपाचे कॉमन्स में मौजूदा समाधान हैं:

आपको बस अपनी पसंद की एन्कोडिंग चुनने की जरूरत है।


7
FYI करें: ReaderInputStream कोड में बग को पढ़ने के तरीके में एक बग है (यह सभी एन्कोडिंग के लिए काम नहीं करेगा)। प्रमाण: illegalargumentexception.blogspot.com/2009/05/… एक खुला बग है: issues.apache.org/bugzilla/show_bug.cgi?id=40455
McDowell

1
आप अपाचे के
कॉमन्स-

@ मैकडॉवेल, आपके द्वारा उल्लिखित बग अपाचे चींटी के कार्यान्वयन में है, कॉमन्स-आईओ में नहीं है, इसलिए यह इस उत्तर के लिए प्रासंगिक नहीं है।
रोमन

94

यदि आप एक स्ट्रिंग के साथ शुरू कर रहे हैं तो आप निम्न कार्य भी कर सकते हैं:

new ByteArrayInputStream(inputString.getBytes("UTF-8"))

7
अच्छे ReaderInputStreamकार्यान्वयन के लिए कम मेमोरी की आवश्यकता होगी - एक बार में सभी बाइट्स को किसी सरणी में संग्रहीत करने की आवश्यकता नहीं होनी चाहिए।
पियोट फाइंडसेन

3
जब आप इकाई परीक्षण कोड की आवश्यकता होती है, जो इनपुट पर (जैसे) मानक इनपुट को स्वीकार करता है, तो इसके लिए मुझे यह समाधान पसंद है।
केदार म्हसवडे

43

खैर, एक पाठक पात्रों के साथ व्यवहार करता है और एक इनपुटस्ट्रीम बाइट्स से संबंधित है। एन्कोडिंग निर्दिष्ट करता है कि आप बाइट के रूप में अपने पात्रों का प्रतिनिधित्व कैसे करना चाहते हैं, इसलिए आप वास्तव में इस मुद्दे को अनदेखा नहीं कर सकते। समस्याओं से बचने के लिए, मेरी राय है: एक चारसेट (जैसे "यूटीएफ -8") चुनें और उसके साथ रहें।

वास्तव में इसे कैसे करना है, इस बारे में, जैसा कि बताया गया है, " इन वर्गों के लिए स्पष्ट नाम ReaderInputStream और WriterOutputStream हैं " हैरानी की बात है, " ये जावा लाइब्रेरी में शामिल नहीं हैं " भले ही "विपरीत" कक्षाएं, InputStreamReader और OutputStreamWriter हैं। शामिल थे।

इसलिए, बहुत से लोग अपने स्वयं के कार्यान्वयन के साथ आए हैं, जिसमें Apache Commons IO भी शामिल है । लाइसेंसिंग के मुद्दों के आधार पर, आप संभवतः अपने प्रोजेक्ट में कॉमन्स-आईआईओ लाइब्रेरी शामिल कर सकते हैं, या यहां तक ​​कि सोर्स कोड (जो यहां डाउनलोड करने योग्य है ) के एक हिस्से को कॉपी कर सकते हैं ।

जैसा कि आप देख सकते हैं, दोनों वर्गों के प्रलेखन में कहा गया है कि "JRE द्वारा समर्थित सभी चारसेट एन्कोडिंग को सही तरीके से संभाला गया है"।

एनबी ए अन्य जवाबों में से एक पर टिप्पणी इस बग का उल्लेख करता है । लेकिन उस अपाचे को प्रभावित करता है चींटी ReaderInputStream वर्ग ( यहाँ ), नहीं अपाचे कॉमन्स आईओ ReaderInputStream वर्ग।


19

यह भी ध्यान रखें कि, यदि आप एक स्ट्रिंग के साथ बंद शुरू कर रहे हैं, तो आप एक StringReader बनाने छोड़ सकते हैं और से org.apache.commons.io.IOUtils का उपयोग कर एक कदम में एक InputStream बना सकते हैं कॉमन्स आईओ इसलिए की तरह:

InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");

बेशक आपको अभी भी पाठ एन्कोडिंग के बारे में सोचने की ज़रूरत है, लेकिन कम से कम रूपांतरण एक चरण में हो रहा है।


4
यह विधि मूल रूप से करती है new ByteArrayInputStream(report.toString().getBytes("utf-8")), जिसमें मेमोरी में रिपोर्ट की दो अतिरिक्त प्रतियां आवंटित करना शामिल है। यदि रिपोर्ट बड़ी है, तो यह खराब है। मेरा जवाब देखिए।
ओलिव

8

उपयोग:

new CharSequenceInputStream(html, StandardCharsets.UTF_8);

इस तरह से रिपोर्ट के बड़े होने की स्थिति में, Stringऔर फिर byte[], जो बहुत अधिक ढेर स्मृति आवंटित करता है, के लिए एक अग्रिम रूपांतरण की आवश्यकता नहीं होती है। यह प्रवाह पर बाइट्स को धर्मान्तरित करता है क्योंकि धारा पढ़ी जाती है, स्ट्रिंगबफ़र से सही।

यह Apache Commons IO प्रोजेक्ट से CharSequenceInputStream का उपयोग करता है ।



5

इन वर्गों के लिए स्पष्ट नाम ReaderInputStream और WriterOutputStream हैं। दुर्भाग्य से ये जावा लाइब्रेरी में शामिल नहीं हैं। हालाँकि, Google आपका मित्र है।

मुझे यकीन नहीं है कि यह सभी पाठ एन्कोडिंग समस्याओं के आसपास होने वाला है, जो बुरे सपने हैं।

एक RFE है, लेकिन यह बंद है, ठीक नहीं होगा।


1
Bugs.openjdk.java.net/browse/JDK-4103785 में टिप्पणी है "हमारे पास वर्ण सेट कोडिंग के लिए एक सार्वजनिक API है ... इन वर्गों को जोड़ने के लिए कोई बाध्यकारी कारण नहीं है" - इसलिए जावा 7 में यह कैसे होता है, बिना अतिरिक्त पुस्तकालय, सड़क से बारह साल नीचे?
पायोत्र फाइंडसेन

5

आप पाठ एन्कोडिंग मुद्दों से बच नहीं सकते, लेकिन अपाचे कॉमन्स-आईओआई के पास है

ध्यान दें कि ये koders.com के पीटर के उत्तर में संदर्भित पुस्तकालय हैं, स्रोत कोड के बजाय केवल पुस्तकालय से लिंक करते हैं।


4

आप एक की सामग्री लिखने के लिए कोशिश कर रहे हैं Readerएक करने के लिए OutputStream? यदि हां, तो आप एक आसान समय लपेटकर होगा OutputStreamएक में OutputStreamWriterऔर लिखने charसे रों Readerकरने Writerके बजाय एक पाठक कन्वर्ट करने के लिए कोशिश कर के InputStream:

final Writer writer = new BufferedWriter(new OutputStreamWriter( urlConnection.getOutputStream(), "UTF-8" ) );
int charsRead;
char[] cbuf = new char[1024];
while ((charsRead = data.read(cbuf)) != -1) {
    writer.write(cbuf, 0, charsRead);
}
writer.flush();
// don't forget to close the writer in a finally {} block

1

WriterOutputStream का उपयोग करते समय एक चेतावनी - यह हमेशा बाइनरी डेटा को एक फ़ाइल को ठीक से लिखने में सक्षम नहीं करता है / एक नियमित आउटपुट स्ट्रीम के समान है। मेरे पास इसके साथ एक मुद्दा था जिसने मुझे ट्रैक करने में थोड़ी देर लगाई।

यदि आप कर सकते हैं, तो मैं आपके आधार के रूप में एक आउटपुट स्ट्रीम का उपयोग करने की सलाह दूंगा, और यदि आपको स्ट्रिंग्स लिखने की आवश्यकता है, तो इसे करने के लिए स्ट्रीम के चारों ओर एक OUtputStreamWriter आवरण का उपयोग करें। यह टेक्स्ट को बाइट्स के चारों ओर से दूसरे तरीके से बदलने के लिए अधिक विश्वसनीय है, यही वजह है कि WriterOutputStream मानक जावा लाइब्रेरी का हिस्सा नहीं है



-1

सिर्फ जावा की आपूर्ति का उपयोग करके एक धारा में एक स्ट्रिंग पढ़ने के लिए।

InputStream s = new BufferedInputStream( new ReaderInputStream( new StringReader("a string")));

6
ReaderInputStream Apache Commons IO में है।
विल बेंसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.