मैंने इस मुद्दे पर अन्य पोस्ट पढ़ी हैं, लेकिन उनके द्वारा प्रस्तुत समाधान मेरे काम नहीं आया। वास्तव में, आधिकारिक जावा दस्तावेज़ीकरण भी अपेक्षित रूप से काम नहीं करता था (मैं जावा 11 का उपयोग कर रहा हूँ): https://docs.oracle.com/javase/tutorial/i18n/text/string.html
मेरी समस्या यह है कि मैं एक बाइट बफर से एक समय में एक बाइट पढ़ रहा हूं, उसे बाइट सरणी में डाल रहा हूं, और उस बाइट सरणी से स्ट्रिंग बना रहा हूं। मेरे द्वारा पढ़े गए बाइट एक एम्बेडेड सिस्टम से हैं जो केवल ISO-8859-1 बाइट्स भेज सकते हैं, इसलिए मैं ISO-8859-1 बाइट्स के साथ एक बाइट सरणी के साथ समाप्त होता हूं और जावा स्ट्रिंग जो मुझे मिल रही है वह इस प्रकार ISO-8859-1 है एन्कोडेड। यहां कोई समस्या नहीं है। IntelliJ में स्ट्रिंग इस तरह दिखती है:
मैं जिन बाइट्स को ISO-8859-1 से UTF-8 में बदलने की कोशिश कर रहा हूं, वे पीले रंग के हैं। मैं चाहता हूं कि वे यूटीएफ -8 हों, इसलिए अंत में "सी 9" बाइट को "सी 3 ए 9" बाइट्स द्वारा प्रतिस्थापित किया जाना चाहिए।
पहला चरण सही ढंग से काम करता है, मैं यह करता हूं: maintenanceResponseString.getBytes(StandardCharsets.UTF_8)
और मुझे सही बाइट मिलते हैं जो मुझे चाहिए, स्ट्रिंग का UTF-8 एन्कोडिंग, यह अच्छा है:
समस्या यहां आती है, जब मैं इन नए (और GOOD) बाइट्स में से एक STRING बनाने का प्रयास करता हूं, जैसे:
new String(maintenanceResponseString.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8)
पुराने बाइट वापस आ गए हैं ?!! यह "getBytes (UTF-8)" जैसा है जो वास्तव में कभी नहीं हुआ। दस्तावेज़ीकरण कहता है कि ऐसा नहीं होना चाहिए... मैं यहाँ क्या खो रहा हूँ? मैंने परीक्षण किए हैं और स्ट्रिंग वास्तव में अभी भी आईएसओ-८८५९-१ एन्कोडेड है... मुझे नहीं पता कि यहां क्या हो रहा है। "गेटबाइट्स" से बाइट कहां हैं?
आप एक स्ट्रिंग को कैसे परिवर्तित करते हैं जिसमें ISO-8859-1 बाइट्स को UTF-8 बाइट्स में शामिल किया गया है? मैं विकल्पों से बाहर हूँ और मुझे इसे एक प्रो प्रोजेक्ट के लिए वास्तविक रूप से खराब करने की आवश्यकता है ... यह आसान होना चाहिए!
नोट: मैंने विकल्पों की कोशिश की है जैसे
ByteBuffer buffer = StandardCharsets.UTF_8.encode(s);
return StandardCharsets.UTF_8.decode(buffer).toString();
लेकिन ठीक ऐसा ही होता है।
मदद के लिए पहले ही धन्यवाद।
संपादित करें: टिप्पणियों में कुछ जानकारी के साथ कि जावा 9+ में स्ट्रिंग्स को आंतरिक रूप से यूटीएफ -16 के रूप में नहीं, बल्कि लैटिन -1 (क्यों ...) लैटिन -1" जब यह स्ट्रिंग का केवल डिफ़ॉल्ट प्रतिनिधित्व है यदि हम उस एन्कोडिंग को निर्दिष्ट नहीं करते हैं जिसे हम स्ट्रिंग प्रदर्शित करते समय उपयोग करना चाहते हैं।
अब जो मुझे समझ में नहीं आता है, वह स्ट्रिंग स्वयं किसी भी एन्कोडिंग के लिए बाध्य नहीं है, और आप उस एन्कोडिंग को चुन सकते हैं जिसे आप इसे लिखे जाने पर प्रदर्शित करना चाहते हैं। असल में मेरा मुद्दा यह है कि स्ट्रिंग समाप्त होती है जिसे लैटिन -1 में जेएक्सबी मार्शलिंग के माध्यम से एक एक्सएमएल फ़ाइल में लिखा जाता है, और अब मुझे लगता है कि मुद्दे वहीं हैं ... जब मैं अपने काम के कंप्यूटर को फिर से एक्सेस करता हूं और यहां रिपोर्ट करता हूं तो मैं और खोदूंगा
1 उत्तर
यह पता चला है कि स्ट्रिंग्स और "उनके एन्कोडिंग" में कुछ भी गलत नहीं था। क्या हुआ मैं वास्तव में भ्रमित हो गया क्योंकि डीबगर स्ट्रिंग की सामग्री को "डिफ़ॉल्ट आंतरिक स्टोरेज एन्कोडिंग" में दिखाता है, और वह आईएसओ -885 9 -1 है (लेकिन यूटीएफ -16 हो सकता है, स्ट्रिंग की सामग्री पर निर्भर करता है)।
JEP-254 से उद्धरण:
हम स्ट्रिंग वर्ग के आंतरिक प्रतिनिधित्व को UTF-16 चार सरणी से एक बाइट सरणी और एक एन्कोडिंग-फ्लैग फ़ील्ड में बदलने का प्रस्ताव करते हैं। नया स्ट्रिंग वर्ग स्ट्रिंग की सामग्री के आधार पर या तो ISO-8859-1/लैटिन-1 (एक बाइट प्रति वर्ण), या UTF-16 (प्रति वर्ण दो बाइट्स) के रूप में एन्कोड किए गए वर्णों को संग्रहीत करेगा। एन्कोडिंग ध्वज इंगित करेगा कि कौन सा एन्कोडिंग उपयोग किया जाता है।
लेकिन वास्तव में यह आंतरिक एन्कोडिंग भंडारण से कोई फर्क नहीं पड़ता। जब लिखने का समय हो, तो स्ट्रिंग लेखन के समय आप जो भी एन्कोडिंग चाहते हैं उसका उपयोग करेंगे।
मेरी समस्या वास्तव में तब थी जब मैं स्प्रिंग रेस्ट टेम्पलेट के साथ एक HTTP अनुरोध में स्ट्रिंग भेज रहा था। मेरे पास अनुरोध में उपयोग करने के लिए "वर्णसेट" निर्दिष्ट करने वाला शीर्षलेख नहीं था, और यदि अन्यथा नहीं बताया गया तो RestTemplate ISO-8859-1 पर डिफ़ॉल्ट है। मैंने वर्णसेट = utf-8 जोड़ा, और स्ट्रिंग को अनुरोध में UTF-8 के रूप में सही ढंग से लिखा गया था।
मदद के लिए @VGR @Eugene @skomisa को धन्यवाद
संबंधित सवाल
नए सवाल
java
जावा एक उच्च स्तरीय प्रोग्रामिंग भाषा है। इस टैग का उपयोग तब करें जब आपको भाषा का उपयोग करने या समझने में समस्या हो। इस टैग का उपयोग शायद ही कभी किया जाता है और इसका उपयोग अक्सर [वसंत], [वसंत-बूट], [जकार्ता-ई], [Android], [javafx], [हडूप], [श्रेणी] और [मावेन] के साथ किया जाता है।
char
मान याint
कोडपॉइंट मान के रूप में एक्सेस कर सकता है।)new String(maintenanceResponseString.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8)
कुछ भी न करने के समान है। यह एक व्यर्थ दौर की यात्रा है।byte[]
के रूप में संग्रहीत हैं और एन्कोडर या तोLATIN-1
याUTF-16
है, लेकिन हां, यह केवल आंतरिक रूप से है।UTF_8
का उपयोग करके किसी भी तरह उन आईएसओ 8859-1 बाइट्स को सही ढंग से डीकोड किया गया।