क्या टेक्स्ट एन्कोडिंग समस्याओं से निपटने से बचने का कोई आसान तरीका है?रीडर को इनपुटस्ट्रीम में और आउटपुटस्ट्रीम के लिए एक लेखक को कैसे परिवर्तित करें?
उत्तर
आप वास्तव में पाठ एन्कोडिंग के मुद्दों से निपटने से बचने नहीं कर सकते हैं, लेकिन मौजूदा समाधान हैं:
Reader
InputStream
रहे हैं:ReaderInputStream
Writer
OutputStream
रहे हैं:WriterOutputStream
तुम बस अपनी पसंद के एन्कोडिंग को चुनने की जरूरत है।
इन कक्षाओं के लिए स्पष्ट नाम ReaderInputStream और WriterOutputStream हैं। दुर्भाग्य से ये जावा पुस्तकालय में शामिल नहीं हैं। हालांकि, गूगल आपका दोस्त है।
मुझे यकीन नहीं है कि यह सभी टेक्स्ट एन्कोडिंग समस्याओं के आसपास जा रहा है, जो कि दुःस्वप्न हैं।
There is an RFE, लेकिन यह बंद है, ठीक नहीं होगा।
https://bugs.openjdk.java.net/browse/JDK-4103785 टिप्पणी में शामिल है "हम इन्हें जोड़ने के लिए चरित्र सेट कोडिंग ... कोई बाध्यकारी कारण के लिए एक सार्वजनिक एपीआई है कक्षाएं "- तो जावा 7 में यह कैसे करता है, अतिरिक्त पुस्तकालयों के बिना, सड़क के नीचे बारह साल? –
क्या आप 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
भी ध्यान रखें कि, यदि आप एक स्ट्रिंग के साथ बंद शुरू कर रहे हैं, तो आप ऐसा तरह Commons IO से एक StringReader बनाने छोड़ सकते हैं और एक कदम में एक InputStream बना सकते हैं org.apache.commons.io.IOUtils का उपयोग कर:
InputStream myInputStream = IOUtils.toInputStream(reportContents, "UTF-8");
बेशक
तुम अब भी जरूरत है टेक्स्ट एन्कोडिंग के बारे में सोचने के लिए, लेकिन ली पर सेंट एक रूपांतरण में हो रहा है।
यह विधि मूल रूप से 'नया है ByteArrayInputStream (report.toString()। GetBytes ("utf-8")) ', जिसमें स्मृति में रिपोर्ट की दो अतिरिक्त प्रतियों का आवंटन शामिल है। यदि रिपोर्ट बड़ी है, तो यह बुरा है। मेरा उत्तर देखें। – Oliv
आप एक स्ट्रिंग के साथ बंद शुरू कर रहे हैं, तो आप भी ऐसा कर सकते हैं निम्नलिखित:
new ByteArrayInputStream(inputString.getBytes("UTF-8"))
यह हल करता है स्ट्रिंग के साथ समस्या, लेकिन मूल – sbeliakov
अच्छा 'रीडर इनपुट स्ट्रीम' कार्यान्वयन के लिए कम स्मृति की आवश्यकता नहीं होगी - एक बार में सभी बाइट्स को एक बार में स्टोर करने की आवश्यकता नहीं होनी चाहिए। –
मुझे यह समाधान पसंद है जब आपको इकाई की आवश्यकता होती है परीक्षण कोड जो इनपुट इनपुट (उदा।) इनपुट इनपुट स्वीकार करता है। –
आप पाठ एन्कोडिंग मुद्दों से बचने नहीं कर सकते, लेकिन Apache commons-io
ध्यान दें कि ये कोडर्स.com के पीटर के उत्तर में संदर्भित पुस्तकालय हैं, जो स्रोत कोड के बजाय लाइब्रेरी से लिंक हैं।
ठीक है, एक पाठक पात्रों से संबंधित है और बाइट्स के साथ एक इनपुटस्ट्रीम सौदों। एन्कोडिंग निर्दिष्ट करता है कि आप बाइट्स के रूप में अपने पात्रों का प्रतिनिधित्व कैसे करना चाहते हैं, ताकि आप वास्तव में इस मुद्दे को अनदेखा नहीं कर सकें। समस्याओं से बचने के लिए, मेरी राय है: एक वर्णमाला (उदा। "यूटीएफ -8") चुनें और इसके साथ चिपके रहें।
के बारे में कैसे वास्तव में यह, के रूप में बताया गया है, करने के लिए "इन कक्षाओं के लिए स्पष्ट नाम ReaderInputStream और WriterOutputStream हैं।" हैरानी की बात है, "इन जावा पुस्तकालय में शामिल नहीं हैं" भले ही 'विपरीत' वर्ग, InputStreamReader और OutputStreamWriter शामिल हैं।
तो, बहुत से लोग अपाचेCommons IO सहित अपने स्वयं के कार्यान्वयन के साथ आए हैं। लाइसेंसिंग मुद्दों के आधार पर, आप शायद अपने प्रोजेक्ट में कॉमन्स-आईओ लाइब्रेरी को शामिल करने में सक्षम होंगे, या यहां तक कि स्रोत कोड के एक हिस्से की प्रतिलिपि भी लेंगे (जो here डाउनलोड करने योग्य है)।
- अपाचे ReaderInputStream: API/source code direct link
- अपाचे WriterOutputStream: API/source code direct link
आप देख सकते हैं, दोनों वर्गों 'प्रलेखन कहा गया है कि "सभी चारसेट JRE द्वारा समर्थित एन्कोडिंग सही ढंग से नियंत्रित किया जाता है" ।
एनबी। यहां अन्य उत्तरों में से एक पर टिप्पणी this bug का उल्लेख करती है। लेकिन उस अपाचे चींटी ReaderInputStream वर्ग (here), नहीं अपाचे कॉमन्स आईओ ReaderInputStream वर्ग को प्रभावित करता है।
WriterOutputStream का उपयोग करते समय एक चेतावनी - यह हमेशा एक फ़ाइल में उचित बाइनरी डेटा को नियमित रूप से/एक नियमित आउटपुट स्ट्रीम के रूप में संभालती नहीं है। मुझे इस बात का कोई मुद्दा था कि मुझे ट्रैक करने में थोड़ी देर लग गई।
यदि आप कर सकते हैं, तो मैं आपके आधार के रूप में आउटपुट स्ट्रीम का उपयोग करने की अनुशंसा करता हूं, और यदि आपको तार लिखने की आवश्यकता है, तो इसे करने के लिए स्ट्रीम के चारों ओर एक OUtputStreamWriter wrapper का उपयोग करें।
new CharSequenceInputStream(html, StandardCharsets.UTF_8);
इस तरह एक अग्रिम की आवश्यकता नहीं है: यह दूसरी तरह के आसपास है, जो की संभावना है की तुलना में बाइट्स के लिए पाठ परिवर्तित करने के लिए क्यों WriterOutputStream मानक जावा पुस्तकालय का एक हिस्सा नहीं है
उपयोग कहीं अधिक विश्वसनीय है String
और फिर byte[]
में रूपांतरण, जो रिपोर्ट बड़ी है, में बहुत अधिक ढेर स्मृति आवंटित करता है। यह फ्लाई पर बाइट्स में बदल जाता है क्योंकि स्ट्रिंगबफर से सीधे स्ट्रीम पढ़ी जाती है।
यह अपाचे कॉमन्स आईओ प्रोजेक्ट से CharSequenceInputStream का उपयोग करता है।
केवल जावा आपूर्ति का उपयोग करके स्ट्रीम में एक स्ट्रिंग पढ़ने के लिए।
InputStream s = new BufferedInputStream(new ReaderInputStream(new StringReader("a string")));
ReaderInputStream Apache Commons IO में है। –
आप Cactoos (कोई स्थिर तरीकों, केवल वस्तुओं) का उपयोग कर सकते हैं:
-
:
new ReaderOf(inputStream)
new WriterTo(outputStream)
आप अन्य तरह से भी चारों ओर परिवर्तित कर सकते हैं
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
कोड भी कॉपीराइट है :( – Armand
आप अपाचे के कॉमन्स-io लाइब्रेरी में कक्षाएं पा सकते हैं: http://commons.apache.org/proper/commons-io/ –