2010-05-04 18 views
10

मुझे कुछ फ्रांसीसी पाठ को यूटीएफ 8 में परिवर्तित करने में कुछ समस्याएं आ रही हैं ताकि इसे कंसोल, टेक्स्ट फ़ाइल या जीयूआई तत्व में ठीक से प्रदर्शित किया जा सके।जावा में यूटीएफ -8 वर्ण एन्कोडिंग

मूल स्ट्रिंग

HANDICAP╔ES

जो

HANDICAPÉES

कोड स्निपेट कि दिखाता है कि कैसे मैं jackcess डाटाबेस ड्राइवर का उपयोग कर रहा पढ़ने के लिए है माना जाता है है एक ग्रहण/लिनक्स पर्यावरण में Acccess एमडीबी फ़ाइल में।

Database database = Database.open(new File(filepath)); 
Table table = database.getTable(tableName, true); 
Iterator rowIter = table.iterator(); 
while (rowIter.hasNext()) { 
    Map<String, Object> row = this.rowIter.next(); 
    // convert fields to UTF 
    Map<String, Object> rowUTF = new HashMap<String, Object>(); 
    try { 
     for (String key : row.keySet()) { 
      Object o = row.get(key); 
      if (o != null) { 
       String valueCP850 = o.toString(); 
       // String nameUTF8 = new String(valueCP850.getBytes("CP850"), "UTF8"); // does not work! 
       String valueISO = new String(valueCP850.getBytes("CP850"), "ISO-8859-1"); 
       String valueUTF8 = new String(valueISO.getBytes(), "UTF-8"); // works! 
       rowUTF.put(key, valueUTF8); 
      } 
     } 
    } catch (UnsupportedEncodingException e) { 
     System.err.println("Encoding exception: " + e); 
    } 
} 

कोड आप देखेंगे जहाँ मैं UTF8, जो काम करने के लिए प्रतीत नहीं होता है करने के लिए सीधे परिवर्तित करना चाहते हैं में, तो मैं एक डबल रूपांतरण करना है। यह भी ध्यान रखें कि जैकस ड्राइवर का उपयोग करते समय एन्कोडिंग प्रकार निर्दिष्ट करने का कोई तरीका प्रतीत नहीं होता है।

धन्यवाद, कैम

+1

यह यूटीएफ -8 नहीं बल्कि सीपी 850 है। – Joey

+0

क्या आप कह रहे हैं कि मूल स्ट्रिंग CP850 है? मुझे एहसास है कि मूल स्ट्रिंग यूटीएफ -8 नहीं थी, हालांकि मुझे यकीन नहीं था कि कौन सा सटीक एन्कोडिंग है। यह यूटीएफ -8 है कि मैं इसे बदलने की कोशिश कर रहा हूं ताकि यह ठीक से प्रदर्शित हो सके। और यह मेरी समझ है कि ए चरित्र यूटीएफ -8 द्वारा समर्थित है। धन्यवाद। – cambo

+3

'╔' जब आप CP1252 में 'É' लेते हैं और इसे CP850 के रूप में समझते हैं तो आपको मिलता है। – Joey

उत्तर

9

नए विश्लेषण, नई जानकारी के आधार पर।
ऐसा लगता है कि आपकी समस्या पाठ की एन्कोडिंग से पहले ही पहुँच DB में जमा हो गया था के साथ है। ऐसा लगता है कि इसे आईएसओ -885 9 -1 या विंडोज -1252 के रूप में एन्कोड किया गया था, लेकिन सीपी 850 के रूप में डीकोड किया गया था, जिसके परिणामस्वरूप डीबी में HANDICAP╔ES स्ट्रिंग किया जा रहा था।

डीबी से उस स्ट्रिंग को सही तरीके से पुनर्प्राप्त करने के बाद, अब आप मूल एन्कोडिंग त्रुटि को वापस करने की कोशिश कर रहे हैं और स्ट्रिंग को पुनर्प्राप्त करने की कोशिश कर रहे हैं क्योंकि इसे संग्रहीत किया जाना चाहिए: HANDICAPÉES। और अगर आप इस लाइन के साथ कि पूरा कर रहे:

String valueISO = new String(valueCP850.getBytes("CP850"), "ISO-8859-1"); 

getBytes("CP850") बाइट मूल्य 0xC9 के चरित्र बदल देता है, और स्ट्रिंग निर्माता डीकोड कि ISO-8859-1 के अनुसार, चरित्र É हो जाती है। अगली पंक्ति:

String valueUTF8 = new String(valueISO.getBytes(), "UTF-8"); 

... कुछ भी नहीं करता है। getBytes() प्लेटफ़ॉर्म डिफ़ॉल्ट एन्कोडिंग में स्ट्रिंग को एन्कोड करता है, जो आपके लिनक्स सिस्टम पर यूटीएफ -8 है। फिर स्ट्रिंग कन्स्ट्रक्टर इसे उसी एन्कोडिंग के साथ डीकोड करता है। उस रेखा को हटाएं और आपको अभी भी वही परिणाम मिलना चाहिए।

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

और यदि मेरा विश्लेषण सही है, तो आपका एक्सेस ड्राइवर सही ढंग से डीकोडिंग कर रहा है; समस्या दूसरी तरफ है, संभवतः डीबी भी तस्वीर में आने से पहले। यह है जिसे आपको ठीक करने की आवश्यकता है, क्योंकि new String(getBytes()) हैक सभी मामलों में काम पर गिना नहीं जा सकता है।


मूल विश्लेषण, कोई जानकारी के आधार पर।: -/
यदि आप कंसोल पर HANDICAP╔ES देख रहे हैं, तो शायद कोई समस्या नहीं है।इस कोड को देखते हुए:

System.out.println("HANDICAPÉES"); 

JVM धर्मान्तरित मंच डिफ़ॉल्ट एन्कोडिंग, windows-1252 के लिए (यूनिकोड) स्ट्रिंग, यह कंसोल के लिए भेजने से पहले। फिर कंसोल डीकोड करता है कि अपने डिफ़ॉल्ट एन्कोडिंग का उपयोग करके, जो cp850 होता है। तो कंसोल इसे गलत दिखाता है, लेकिन यह सामान्य है। आप इसे सही ढंग से प्रदर्शित करना चाहते हैं, तो आप इस आदेश के साथ सांत्वना के कूट बदल सकते हैं:

CHCP 1252 

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

एक फाइल करने के लिए लिखने के लिए के रूप में, बस वांछित एन्कोडिंग निर्दिष्ट:

OutputStreamWriter osw = new OutputStreamWriter(
    new FileOutputStream("myFile.txt"), "UTF-8"); 
+0

मुझे लगता है कि मुझे अपने विकास पर्यावरण के बारे में और अधिक स्पष्ट होना चाहिए था। विकास के लिए, मैं उबंटू लिनक्स मशीन पर ग्रहण का उपयोग कर रहा हूं। मुझे वही परिणाम मिलते हैं चाहे मैं इसे ग्रहण कंसोल से या नियमित टर्मिनल कंसोल से चलाता हूं। हम एक्सेस एमडीबी डेटाबेस फ़ाइल को पढ़ने के लिए जैक जावा जावा एपीआई का उपयोग कर रहे हैं। जैकस ड्राइवर के लिए डिफ़ॉल्ट एन्कोडिंग निर्दिष्ट करने का कोई तरीका नहीं है, इसलिए मुझे ऊपर वर्णित रूपांतरण करना है। मैंने स्ट्रिंग को सीधे एक जीयूआई तत्व (जेएलएबल, जेटेक्स्टफिल्ड) में आउटपुट करने का प्रयास किया लेकिन इससे कोई मदद नहीं मिली। – cambo

+0

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

+0

ठीक है, मैंने डेटा को पुनर्प्राप्त करने के लिए उपयोग किए जा रहे कोड का नमूना दिखाने के लिए प्रश्न संपादित किया है। धन्यवाद। – cambo

8
String s = "HANDICAP╔ES"; 
System.out.println(new String(s.getBytes("CP850"), "ISO-8859-1")); // HANDICAPÉES 

यह सही स्ट्रिंग मान को दर्शाता है। इसका मतलब यह है कि यह मूल रूप से एन्कोडेड/ISO-8859-1 साथ डीकोड और उसके बाद गलत तरीके सेके रूप में एक टिप्पणी में बताया CP850 (मूल रूप से CP1252 उर्फ ​​विंडोज एएनएसआई साथ इनकोडिंग भी संभव हो गया था वास्तव में के बाद से É ही कोडपॉइंट वहाँ है आईएसओ 8859- में के रूप में किया जाता है 1)।

सभी एक और एक ही चरित्र एन्कोडिंग का उपयोग करने के लिए अपने पर्यावरण और बाइनरी पाइपलाइनों को संरेखित करें। आप उनके बीच परिवर्तित नहीं कर सकते हैं और नहीं करना चाहिए। आप इस तरह से गैर-ASCII रेंज में जानकारी खोने का जोखिम उठाएंगे।

नोट: समस्या को ठीक करने के लिए उपरोक्त कोड स्निपेट का उपयोग न करें! यह सही समाधान नहीं होगा।


अद्यतन: आप जाहिरा तौर पर अभी भी समस्या के साथ संघर्ष कर रहे हैं। मैं जवाब के महत्वपूर्ण हिस्से दोहराने की आवश्यकता होगी:

  1. सभीएक और ही वर्ण एन्कोडिंग का उपयोग करने के लिए अपने पर्यावरण और बाइनरी पाइपलाइनों संरेखित करें।

  2. आप कर सकते हैं नहीं और उन दोनों के बीच परिवर्तित नहीं चाहिए। आपको को गैर-ASCII श्रेणी में इस तरह की जानकारी खोने का जोखिम होगा।

  3. समस्या को ठीक करने के लिए उपरोक्त कोड स्निपेट का उपयोग करें! यह सही समाधान नहीं होगा।

समस्या को ठीक करने के लिए आपको चरित्र एन्कोडिंग एक्स चुनने की आवश्यकता है जिसे आप पूरे एप्लिकेशन में उपयोग करना चाहते हैं। मैं UTF-8 का सुझाव देता हूं। अद्यतन एमएस एक्सेस एन्कोडिंग एक्स उपयोग करने के लिए अपने विकास के वातावरण अद्यतन एन्कोडिंग एक्स अपने कोड में अद्यतन java.io पाठकों और लेखकों उपयोग करने के लिए एन्कोडिंग एक्स उपयोग करने के लिए अपने संपादक अद्यतन एन्कोडिंग एक्स के साथ पढ़ने/फ़ाइलें लिखने के लिए आवेदन के उपयोगकर्ता इंटरफ़ेस अद्यतन का उपयोग करने के एन्कोडिंग एक्स। वाई या जेड या कुछ भी कदम पर उपयोग करें। पात्रों पहले से ही कुछ डेटासंग्रह (एमएस एक्सेस, फ़ाइलें, आदि) में भ्रष्ट हैं, तो आप मैन्युअल रूप से डेटासंग्रह में वहीं पात्रों की जगह करके इसे ठीक करने की जरूरत है। इसके लिए जावा का प्रयोग न करें।

आप वास्तव में यूजर इंटरफेस के रूप में "कमांड प्रॉम्प्ट" का उपयोग कर रहे हैं, तो आप वास्तव में खो रहे हैं। यह यूटीएफ -8 का समर्थन नहीं करता है। टिप्पणियों में और टिप्पणियों से जुड़े लेख में सुझाए गए अनुसार, आपको प्रतिबंधित कमांड प्रॉम्प्ट वातावरण पर भरोसा करने के बजाय Swing एप्लिकेशन बनाना होगा।

+0

इस उत्तर के लिए धन्यवाद। जो डेटा मैं प्राप्त कर रहा हूं वह एक्सेस डेटाबेस में है, इसलिए मेरे पास मूल रूप से एन्कोड किए जाने पर नियंत्रण नहीं है। मुझे लगता है कि मुझे इसे पढ़ने और इसे करने से पहले उचित प्रारूप में बदलने की जरूरत है। इसके अलावा, हम अपने आवेदन में सब कुछ के लिए मानक बनाने और यूटीएफ -8 का उपयोग करने की कोशिश कर रहे हैं। क्या यूटीएफ -8 इन पात्रों का समर्थन नहीं करता है? – cambo

+2

आपको उचित एन्कोडिंग का उपयोग करने के लिए जेडीबीसी ड्राइवर और/या डेटाबेस को निर्देश देना होगा (वह डेटाबेस जिसे स्वयं उपयोग कर रहा है!)। यूटीएफ -8 निश्चित रूप से उन पात्रों का समर्थन करता है, लेकिन एक अलग द्विआधारी प्रतिनिधित्व के साथ, यदि आप समझते हैं कि मेरा क्या मतलब है। अक्षर अर्थात् सबकुछ हैं- बाइट्स के रूप में स्थानांतरित। बस क्योंकि कंप्यूटर कुछ और समझ में नहीं आता है। [यह आलेख] (http://balusc.blogspot.com/2009/05/unicode-how-to-get-characters-right.html) हुड के तहत समस्या को समझने में और मदद कर सकता है। – BalusC

+0

जानकारी और लिंक के लिए धन्यवाद, यह एक अच्छा लेख है! – cambo

-1

का उपयोग करना "ISO-8859-1" मुझे फ्रेंच charactes से निपटने में मदद की।

0

कनेक्शन स्थापित करते समय आप एन्कोडिंग निर्दिष्ट कर सकते हैं। इस तरह से मेरी एन्कोडिंग समस्या को सही और हल किया गया था:

DatabaseImpl open = DatabaseImpl.open(new File("main.mdb"), true, null, Database.DEFAULT_AUTO_SYNC, java.nio.charset.Charset.availableCharsets().get("windows-1251"), null, null); 
    Table table = open.getTable("FolderInfo"); 
संबंधित मुद्दे