2011-05-25 8 views
11

के साथ शून्य अक्षर मुझे पता है कि यह एक बहुत ही सामान्य सवाल है लेकिन मैं पागल हो रहा हूं।जावा में 1212 से यूटीएफ 8 में कनवर्ट करना: वर्णसेट डिकोडर/एनकोडर

मैं इस कोड का इस्तेमाल किया:

String ucs2Content = new String(bufferToConvert, inputEncoding);   
     byte[] outputBuf = ucs2Content.getBytes(outputEncoding);   
     return outputBuf; 

लेकिन मैंने पढ़ा है कि उपयोग करने के लिए CharsetDecoder और CharsetEncoder (मैं शायद गंतव्य एन्कोडिंग के बाहर कुछ चरित्र के साथ सामग्री है) बेहतर है। मैं तो बस इस कोड को लिखा है लेकिन यह है कि कुछ समस्याएं हैं:

// Create the encoder and decoder for Win1252 
Charset charsetInput = Charset.forName(inputEncoding); 
CharsetDecoder decoder = charsetInput.newDecoder(); 

Charset charsetOutput = Charset.forName(outputEncoding); 
CharsetEncoder encoder = charsetOutput.newEncoder(); 

// Convert the byte array from starting inputEncoding into UCS2 
CharBuffer cbuf = decoder.decode(ByteBuffer.wrap(bufferToConvert)); 

// Convert the internal UCS2 representation into outputEncoding 
ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(cbuf)); 
return bbuf.array(); 

दरअसल इस कोड संलग्न कर देता है के लिए बफ़र अशक्त चरित्र का एक अनुक्रम !!!!!

क्या कोई मुझे बता सकता है कि समस्या कहां है? मैं जावा में एन्कोडिंग रूपांतरण के साथ इतना कुशल नहीं हूँ।

जावा में एन्कोडिंग को परिवर्तित करने का कोई बेहतर तरीका है?

उत्तर

7

आपका समस्या यह है कि ByteBuffer.array() और ByteBuffer के लिए समर्थन की दुकान समर्थन सरणी के मान्य श्रेणी से नहीं एक प्रति के रूप में इस्तेमाल सरणी के लिए एक सीधा संदर्भ देता है। आपको bbuf.limit() का पालन करना होगा (जैसे पीटर ने अपनी प्रतिक्रिया में किया था) और इंडेक्स 0 से bbuf.limit()-1 पर सरणी सामग्री का उपयोग करें।

बैकिंग सरणी में अतिरिक्त 0 मानों का कारण CharsetEncoder द्वारा परिणामी बाइटबफर बनाया गया है, इसकी एक मामूली गड़बड़ी है। प्रत्येक CharsetEncoder में "प्रति बाइट औसत बाइट्स" होता है, जो यूसीएस 2 एन्कोडर के लिए सरल और सही (2 बाइट/चार) लगता है। इस निश्चित मूल्य का पालन करते हुए, CharsetEncoder प्रारंभ में इस मामले में "स्ट्रिंग लम्बाई * औसत बाइट प्रति वर्ण" बाइट्स के साथ बाइटबफर आवंटित करता है। 10 वर्ण लंबी स्ट्रिंग के लिए 20 बाइट्स। यूसीएस 2 चार्सेट एन्कोडर हालांकि बीओएम (बाइट ऑर्डर मार्क) के साथ शुरू होता है, जिसमें 2 बाइट्स भी होते हैं, ताकि 10 में से 9 वर्ण आवंटित बाइटबफर में फिट हो जाएं। CharsetEncoder ओवरफ्लो का पता लगाता है और 2 * एन + 1 (एन बाइटबफर की मूल लंबाई होने के साथ) की लंबाई के साथ एक नया बाइटबफर आवंटित करता है, इस मामले में 2 * 20 + 1 = 41 बाइट्स। चूंकि शेष वर्णों को एन्कोड करने के लिए केवल 21 नए बाइटों में से 2 आवश्यक हैं, इसलिए bbuf.array() से प्राप्त सरणी में 41 बाइट्स की लंबाई होगी, लेकिन bbuf.limit() इंगित करेगा कि केवल पहले 22 प्रविष्टियां वास्तव में उपयोग की जाती हैं।

+0

धन्यवाद, शायद आपने मुझे निराशा के कई घंटे बचाए – pepsi

4

मुझे यकीन नहीं है कि आपको null वर्णों का अनुक्रम कैसे मिलता है। प्रयास करें इस

String outputEncoding = "UTF-8"; 
Charset charsetOutput = Charset.forName(outputEncoding); 
CharsetEncoder encoder = charsetOutput.newEncoder(); 

// Convert the byte array from starting inputEncoding into UCS2 
byte[] bufferToConvert = "Hello World! £€".getBytes(); 
CharBuffer cbuf = decoder.decode(ByteBuffer.wrap(bufferToConvert)); 

// Convert the internal UCS2 representation into outputEncoding 
ByteBuffer bbuf = encoder.encode(CharBuffer.wrap(cbuf)); 
System.out.println(new String(bbuf.array(), 0, bbuf.limit(), charsetOutput)); 

प्रिंट

Hello World! £€ 
+0

लेकिन आपको इनपुट एन्कोडिंग से एक वर्णसेट डिकोडर घोषित करना होगा। कुछ ऐसा: CharsetDecoder डिकोडर = charsetInput.newEncoder() जहां charsetInput = Charset.forName ("cp1252")। – robob

+0

एक समान प्रश्न है: http://stackoverflow.com/questions/1252468/java-converting-string-to-and-from-bytebuffer-and-associated-problems – robob

+0

क्या आपको लगता है कि शून्य अनुक्रम गुम हो सकता है "डिकोडर .flush "और" एन्कोडर.फ्लश "? मैं भी देखता हूं कि आपने अपने कोड में फ्लश() का उपयोग नहीं किया है ... – robob

संबंधित मुद्दे