2016-01-21 6 views
12

तो जावा में 'char' 2 बाइट्स है। (here से सत्यापित किया जा सकता।)जावा एक 3 बाइट यूनिकोड चरित्र को चार प्रकार में फिट कैसे करता है?

मैं इस नमूना कोड है:

public class FooBar { 
    public static void main(String[] args) { 
     String foo = "€"; 
     System.out.println(foo.getBytes().length); 
     final char[] chars = foo.toCharArray(); 
     System.out.println(chars[0]); 
    } 
} 

और उत्पादन इस प्रकार है:

3 
€ 

मेरा प्रश्न, कैसे जावा एक 3 बाइट फिट किया जाता है एक चार डेटा प्रकार में चरित्र? -Dfile.encoding = UTF-8

इसके अलावा, अगर मैं कोड थोड़ा और आगे संपादित करें और निम्नलिखित बयानों जोड़ें::

File baz = new File("baz.txt"); 
final DataOutputStream dataOutputStream = new DataOutputStream(new FileOutputStream(baz)); 
dataOutputStream.writeChar(chars[0]); 
dataOutputStream.flush(); 
dataOutputStream.close(); 

अंतिम फ़ाइल "baz Btw, मैं पैरामीटर के साथ आवेदन चला रहा हूँ .txt "केवल 2 बाइट्स होगा, और यह सही वर्ण नहीं दिखाएगा भले ही मैं इसे यूटीएफ -8 फ़ाइल के रूप में मानूं।

संपादित करें 2: यदि मैं एन्कोडिंग यूटीएफ -16 बीई के साथ फ़ाइल "baz.txt" खोलता हूं, तो मुझे अपने पाठ संपादक में € चरित्र ठीक दिखाई देगा, जो मुझे लगता है कि मुझे लगता है।

+3

जावा आंतरिक रूप से यूटीएफ -16 का उपयोग करता है। Http://stackoverflow.com/questions/9699071/what-is-the-javas-internal-represention-for-string-modified-utf-8-utf-16 –

+0

चार वर्ण नहीं है; यह कम है - जो जावा के साथ सबसे बड़ी समस्याओं में से एक है। यह सब कैसे काम करता है इस पर पूर्ण स्पष्टीकरण के लिए utf8everywhere.org देखें। –

उत्तर

8

String.getBytes() प्लेटफॉर्म के डिफ़ॉल्ट वर्ण एन्कोडिंग का उपयोग करके बाइट्स लौटाता है जो आंतरिक प्रतिनिधित्व से मेल नहीं खाता है।

प्रत्येक चार्ट के लिए राम में 2 बाइट्स का उपयोग करते हुए जावा, जब वर्ण यूटीएफ -8 का उपयोग करके "धारावाहिक" होते हैं, तो वे परिणामस्वरूप बाइट सरणी में एक, दो या तीन बाइट उत्पन्न कर सकते हैं, इस प्रकार यूटीएफ -8 एन्कोडिंग काम करता है।

आपका कोड उदाहरण यूटीएफ -8 का उपयोग कर रहा है। जावा स्ट्रिंग्स को इसके बजाय यूटीएफ -16 का उपयोग करके स्मृति में एन्कोड किया गया है। यूनिकोड कोडपॉइंट्स जो एक 16-बिट चार में फिट नहीं होते हैं उन्हें एक 2-चार जोड़ी का उपयोग करके एन्कोड किया जाएगा जिसे सरोगेट जोड़ी कहा जाता है।

यदि आप String.getBytes() पर पैरामीटर मान पास नहीं करते हैं, तो यह एक बाइट सरणी देता है जिसमें अंतर्निहित ओएस के डिफ़ॉल्ट वर्णसेट का उपयोग करके स्ट्रिंग सामग्री एन्कोड किया जाता है। यदि आप एक यूटीएफ -8 एन्कोडेड सरणी सुनिश्चित करना चाहते हैं तो आपको इसके बजाय GetBytes ("UTF-8") का उपयोग करने की आवश्यकता है।

कॉलिंग स्ट्रिंग.charAt() स्ट्रिंग के इन-मेमोरी स्टोरेज से केवल मूल यूटीएफ -16 एन्कोडेड चार लौटाता है। इस लिंक

की जांच: java utf8 encoding - char, string types

7

जावा UTF-16 (16 बिट) का उपयोग करता है में स्मृति प्रतिनिधित्व के लिए।

वह यूरो प्रतीक उसमें फिट बैठता है, भले ही इसे यूटीएफ -8 में तीन बाइट्स की आवश्यकता हो।

+1

तो एक char हमेशा यूटीएफ -16 एनकोडेड होता है? –

+2

हां, और यह एक समस्या है, क्योंकि यूनिकोड उससे बड़ा है। कुछ यूनिकोड कोडपॉइंट्स को अब जावा में दो वर्णों की आवश्यकता है। इसलिए यदि आप "संपूर्ण सूची" का उपयोग करते हैं तो 'लंबाई' या 'charAt' का परिणाम पूरी तरह से संतोषजनक नहीं हो सकता है। – Thilo

+0

तो पैरामीटर I pass -Dfile.encoding = UTF-8 वास्तव में बहुत कुछ नहीं बदलता है, क्या हम कह सकते हैं? –

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