2009-08-13 25 views
5

मैं जावा में कुछ यूटीएफ -8 तारों को डीकोड करने की कोशिश कर रहा हूं। इन तारों में कुछ यूनिकोड वर्ण शामिल हैं, जैसे सीसी 88 (डायरेरेसिस संयोजन)। http://www.fileformat.info/info/unicode/char/0308/index.htmजावा यूटीएफ -8 अजीब व्यवहार

के अनुसार चरित्र अनुक्रम ठीक लगता है, लेकिन स्ट्रिंग में रूपांतरण के बाद आउटपुट अमान्य है। कोई विचार?

byte[] utf8 = { 105, -52, -120 }; 
System.out.print("{{"); 
for(int i = 0; i < utf8.length; ++i) 
{ 
    int value = utf8[i] & 0xFF; 
    System.out.print(Integer.toHexString(value)); 
} 
System.out.println("}}"); 
System.out.println(">" + new String(utf8, "UTF-8")); 

आउटपुट:

 
    {{69cc88}} 
    >i? 

उत्तर

9

सांत्वना जो आप (उदाहरण के लिए विंडोज़) लिए outputting रहे यूनिकोड समर्थन नहीं कर सकते, और वर्ण वध कर सकते हैं। कंसोल आउटपुट डेटा का एक अच्छा प्रतिनिधित्व नहीं है।

इसके बजाय फ़ाइल को आउटपुट लिखने का प्रयास करें, सुनिश्चित करें कि फ़ाइलवाइटर पर एन्कोडिंग सही है, फिर फ़ाइल को यूनिकोड-अनुकूल संपादक में खोलें।

वैकल्पिक रूप से, यह सुनिश्चित करने के लिए कि डिबगर आप अपेक्षा करते हैं, एक डीबगर का उपयोग करें। बस कंसोल पर भरोसा मत करो।

+0

+1: टर्मिनल (gnome-terminal) में उबंटू 9.04 पर आउटपुट मैं डायरेरेसिस के साथ हूं क्योंकि आप शायद इसकी अपेक्षा करते हैं। –

+0

मुझे यह शब्द "डायरेरेसिस" पसंद है। बातचीत में इसे अक्सर इस्तेमाल करना पड़ सकता है। – skaffman

+1

:) "उमलॉट" भी आज़माएं, और आप शाम का आदमी बन जाएंगे। –

4

कोड ठीक है, लेकिन जैसा कि skaffman ने कहा कि आपका कंसोल शायद उपयुक्त चरित्र का समर्थन नहीं करता है।

यकीन है के लिए परीक्षण करने के लिए, आप चरित्र का यूनिकोड मान प्रिंट करना होगा:

public class Test { 
    public static void main(String[] args) throws Exception { 
     byte[] utf8 = { 105, -52, -120 }; 
     String text = new String(utf8, "UTF-8"); 
     for (int i=0; i < text.length(); i++) { 
      System.out.println(Integer.toHexString(text.charAt(i))); 
     } 
    } 
} 

यह प्रिंट 69, 308 - जो correct है (U + 0069, U + 0308)।

4

आप दोनों सही हैं। धन्यवाद !!

यहाँ कैसे मैं अंत में विंडोज पर समस्या हल हो, ग्रहण में:

  • भागो विन्यास में, तर्क टैब, मैं वी एम तर्क
  • भागो विन्यास में करने के लिए "-Dfile.encoding=UTF-8" जोड़ा, आम टैब , मैं UTF-8

को कंसोल एन्कोडिंग सेट और मैं इस प्रकार कोड संशोधित:

byte[] utf8 = { 105, -52, -120 }; 
System.out.print("{{"); 
for(int i = 0; i < utf8.length; ++i) 
{ 
    int value = utf8[i] & 0xFF; 
    System.out.print(Integer.toHexString(value)); 
} 
System.out.println("}}"); 

PrintStream sysout = new PrintStream(System.out, true, "UTF-8"); 
sysout.print(">" + new String(utf8, "UTF-8")); 

आउटपुट:

 
{{69cc88}} 
> ï 

धन्यवाद!

+0

यदि आपको प्रिंटस्ट्रीम का उपयोग करके डेटा को एन्कोड करने जा रहे हैं तो आपको "-Dfile.encoding = UTF-8" स्विच की आवश्यकता नहीं है। (मैन्युअल रूप से "file.encoding" संपत्ति को सेट करना किसी भी कोड के लिए समस्याग्रस्त हो सकता है जिसे सिस्टम एन्कोडिंग को जानने की आवश्यकता है।) – McDowell

1

जावा, अनजाने में नहीं, यूनिकोड वर्णों को देशी सिस्टम एन्कोडेड बाइट्स में एन्कोड करता है इससे पहले कि यह उन्हें stdout पर लिखता है। कुछ ऑपरेटिंग सिस्टम, जैसे कि कई लिनक्स डिस्ट्रोज़, UTF-8 का उपयोग अपने डिफ़ॉल्ट चरित्र सेट के रूप में करते हैं, जो कि अच्छा है।

विंडोज़ पर विभिन्न प्रकार के पीछे-संगतता कारणों के लिए चीजें अलग-अलग हैं। डिफ़ॉल्ट सिस्टम एन्कोडिंग "ANSI" कोडपेजों में से एक होगी और यदि आप डिफ़ॉल्ट कमांड प्रॉम्प्ट (cmd.exe) खोलते हैं तो यह पुराने "OEM" डॉस कोडपेजों में से एक होगा (हालांकि एएनएसआई और यूनिकोड प्राप्त करना संभव है with a bit of work)।

चूंकि यू +0308 किसी भी "एएनएसआई" चरित्र सेट में नहीं है (शायद आपके मामले में 1252), तो यह एक त्रुटि वर्ण (आमतौर पर एक प्रश्न चिह्न) के रूप में एन्कोड किया जाएगा।

सब कुछ यूनिकोड-सक्षम करने के लिए एक वैकल्पिक normalize के संयोजन अनुक्रम U + 0069 U + 0308 एकल वर्ण U + 00EF के लिए है:

public static void emit(String foo) throws IOException { 
    System.out.println("Literal: " + foo); 
    System.out.print("Hex: "); 
    for (char ch : foo.toCharArray()) { 
     System.out.print(Integer.toHexString(ch & 0xFFFF) + " "); 
    } 
    System.out.println(); 
    } 

    public static void main(String[] args) throws IOException { 
    String foo = "\u0069\u0308"; 
    emit(foo); 
    foo = Normalizer.normalize(foo, Normalizer.Form.NFC); 
    emit(foo); 
    } 

तहत windows-1252, इस कोड को फेंकना होगा:

 
Literal: i? 
Hex: 69 308 
Literal: ï 
Hex: ef 
संबंधित मुद्दे