2008-09-15 5 views

उत्तर

34

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

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

+6

FYI: ReaderInputStream कोड में बाइट्स पढ़ने के तरीके में एक बग है (यह सभी एन्कोडिंग के लिए काम नहीं करेगा)। सबूत: http://illegalargumentexception.blogspot.com/2009/05/java-rough-guide-to-character-encoding.html#javaencoding_stringclass एक खुली बग है: https://issues.apache.org/bugzilla/show_bug .cgi? id = 40455 – McDowell

+0

कोड भी कॉपीराइट है :( – Armand

+1

आप अपाचे के कॉमन्स-io लाइब्रेरी में कक्षाएं पा सकते हैं: http://commons.apache.org/proper/commons-io/ –

5

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

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

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

+1

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

4

क्या आप Reader की सामग्री को OutputStream पर लिखने की कोशिश कर रहे हैं? यदि हां, तो आप एक आसान समय एक OutputStreamWriter में OutputStream लपेटकर है और Writer को Reader से char रों लिखते हैं, बजाय एक 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 
16

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

InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8"); 
बेशक

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

+2

यह विधि मूल रूप से 'नया है ByteArrayInputStream (report.toString()। GetBytes ("utf-8")) ', जिसमें स्मृति में रिपोर्ट की दो अतिरिक्त प्रतियों का आवंटन शामिल है। यदि रिपोर्ट बड़ी है, तो यह बुरा है। मेरा उत्तर देखें। – Oliv

87

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

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

यह हल करता है स्ट्रिंग के साथ समस्या, लेकिन मूल – sbeliakov

+6

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

+3

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

5

आप पाठ एन्कोडिंग मुद्दों से बचने नहीं कर सकते, लेकिन Apache commons-io

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

35

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

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

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

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

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

1

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

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

new CharSequenceInputStream(html, StandardCharsets.UTF_8); 

इस तरह एक अग्रिम की आवश्यकता नहीं है: यह दूसरी तरह के आसपास है, जो की संभावना है की तुलना में बाइट्स के लिए पाठ परिवर्तित करने के लिए क्यों WriterOutputStream मानक जावा पुस्तकालय का एक हिस्सा नहीं है

7

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

यह अपाचे कॉमन्स आईओ प्रोजेक्ट से CharSequenceInputStream का उपयोग करता है।

-1

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

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

ReaderInputStream Apache Commons IO में है। –