UTF-8 tekencodering in Java

Ik heb wat problemen met het krijgen van wat de franse tekst om te zetten naar UTF8, zodat het kan goed worden weergegeven, hetzij in een console, tekst-bestand of in een GUI-element.

De originele string is

HANDICAP É ES

die wordt verondersteld te worden

HANDICAPÉES

Hier is een code fragment dat laat zien hoe ik ben met behulp van de jackcess Database driver te lezen in de Acccess MDB-bestand in een Eclipse/Linux-omgeving.

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);
    }   
}

In de code zie je waar ik wil direct converteren naar UTF8, die niet lijkt te werken, dus ik heb een dubbele conversie. Merk ook op dat er niet lijkt te zijn een manier om aan te geven het type codering bij het gebruik van de jackcess chauffeur.

Bedankt,
Cam

  • Dat is niet UTF-8 maar CP850.
  • Zegt u nu dat de originele string is CP850? Ik realiseer me dat de oorspronkelijke string was geen UTF-8, maar ik was niet zeker welke exacte codering. Het is UTF-8 die ik probeer te zetten, zodat die goed wordt weergegeven. En ik begrijp dat de É karakter wordt ondersteund door de UTF-8. Bedankt.
  • is wat u krijgt wanneer u É in CP1252 en interpreteren als CP850.
InformationsquelleAutor cambo | 2010-05-04



4 Replies
  1. 9

    Nieuwe analyse op basis van nieuwe informatie.

    Het lijkt erop dat uw probleem is met de codering van de tekst voordat het was opgeslagen in de Access-DB. Het lijkt erop dat het was gecodeerd als ISO-8859-1 of windows-1252, maar gedecodeerd als cp850, wat resulteert in de string HANDICAP╔ES wordt opgeslagen in de DB.

    Met correct opgehaald die string van de DB, je bent nu aan het proberen om te keren van de originele codering fout en herstellen van de string als het zou moeten zijn opgeslagen: HANDICAPÉES. En je bent het volbrengen die met deze regel:

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

    getBytes("CP850") zet het karakter de byte waarde 0xC9, en de String constructor decodeert die volgens ISO-8859-1, wat resulteert in het teken É. De volgende regel:

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

    …gebeurt er niets. getBytes() codeert voor de reeks in het platform standaard codering, is UTF-8 op uw Linux-systeem. Dan is de String constructor decodeert ze met de dezelfde codering. Deze regel verwijderen en je moet nog steeds om hetzelfde resultaat te krijgen.

    Meer to the point, je probeert te maken van een “UTF-8 string” is misplaatst. Je hoeft niet om jezelf bezig te houden met de codering van Java ‘ s strings–ze zijn altijd van UTF-16. Wanneer tekst in een Java-applicatie, je hoeft alleen maar om ervoor te zorgen dat u decoderen met de juiste codering.

    En als mijn analyse juist is, uw Access-stuurprogramma is het decoderen van het goed; het probleem ligt aan de andere kant, misschien voor de DB ook in beeld komt. Dat is wat je nodig hebt op te lossen, omdat dat new String(getBytes()) hack kan niet worden gegarandeerd in alle gevallen werken.


    Oorspronkelijke analyse, gebaseerd op geen informatie. :-/

    Als je ziet HANDICAP╔ES op de console, is er waarschijnlijk geen probleem. Gegeven deze code:

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

    De JVM-zet de (Unicode) – string om het platform standaard codering, windows-1252, voordat deze naar de console. Dan is de console decodeert dat het gebruik van zijn eigen standaard codering, die toevallig cp850. Zo geeft de console het verkeerd, maar dat is normaal. Als u wilt dat het beeldscherm correct, kunt u de console codering met deze opdracht:

    CHCP 1252

    Om het scherm tekenreeks in een GUI-element, zoals een JLabel, hoeft u niet te doen. Zorg ervoor dat u een lettertype gebruikt dat kan weer alle tekens, maar dat hoeft helemaal geen probleem voor frans.

    Als voor het schrijven naar een bestand, geef de gewenste codering bij het maken van de Schrijver:

    OutputStreamWriter osw = new OutputStreamWriter(
        new FileOutputStream("myFile.txt"), "UTF-8");
    • Ik denk dat ik moet meer duidelijk zijn over mijn ontwikkeling omgeving. Voor ontwikkeling, gebruik ik Eclipse op een Ubuntu Linux machine. Ik krijg dezelfde resultaten of ik het uitvoeren van de Eclipse console of via een terminal console. We zijn met jackcess Java API voor het lezen van de Access-MDB-database-bestand. Er lijkt geen manier om aan te geven van een standaard codering voor de jackcess chauffeur, dus ik heb om de conversie te doen zoals ik hierboven beschreven. Ik probeerde het uitvoeren van de string direct in een GUI-element (JLabel, JTextField) maar dat was niet te helpen.
    • Ja, dit lijkt nogal een exotische probleem, er was geen hint in de oorspronkelijke vraag. Het zou kunnen helpen als we konden zien de eigenlijke code die je gebruikt om de gegevens op te halen. En niet proberen om dat in een reactie–heb je al gezien hoe goed dat werkt. Het bewerken van de vraag en zet het daar.
    • Ok, ik heb bewerkt met de vraag om een voorbeeld van de code die ik gebruik om de gegevens op te halen. Dank u.
  2. 8
    String s = "HANDICAP╔ES";
    System.out.println(new String(s.getBytes("CP850"), "ISO-8859-1")); //HANDICAPÉES

    Dit geeft de juiste waarde. Dit betekent dat het oorspronkelijk gecodeerd/gedecodeerd met ISO-8859-1 en dan onjuist gecodeerd met CP850 (oorspronkelijk CP1252 een.k.een. Windows ANSI-zoals gezegd in een reactie is inderdaad ook mogelijk omdat de É heeft dezelfde codepoint er zoals in ISO-8859-1).

    Uitlijnen van uw omgeving en binaire pijpleidingen gebruik maken van één en hetzelfde karakter codering. U kan niet en mag niet zetten tussen hen. Zou u het risico het verliezen van informatie in de niet-ASCII – bereik op die manier.

    Opmerking: gebruik de bovenstaande codefragment te “repareren” het probleem! Dat zou niet de juiste oplossing.


    Update: u bent blijkbaar nog steeds worstelen met het probleem. Ik herhaal de belangrijkste onderdelen van het antwoord:

    1. Uitlijnen van uw omgeving en binaire pijpleidingen te gebruiken alle de een en dezelfde karakter codering.

    2. U kunt niet en moet niet zetten tussen hen. U zou het risico verliezen informatie in de niet-ASCII – bereik op die manier.

    3. Doen NIET gebruik de bovenstaande codefragment te “repareren” het probleem! Dat zou niet de recht oplossing.

    Om het probleem te verhelpen moet u kiezen voor karakter codering X die u wilt gebruiken voor de gehele toepassing. Ik stel UTF-8. Update MS Access te gebruiken codering X. Update uw ontwikkelomgeving te gebruiken codering X. de Update van de java.io lezers en schrijvers in uw code te gebruiken codering X. Update uw editor om te lezen/schrijven van bestanden met codering X. de Update van de gebruikersinterface van de toepassing gebruiken codering X. Doen niet gebruik Y of Z of wat dan ook op stap. Indien de tekens zijn al beschadigd in sommige datastore (MS Access, bestanden, etc), dan moet je om het op te lossen door handmatig vervangen van de karakters er in de datastore. Gebruik geen Java voor.

    Als je daadwerkelijk met behulp van de “command prompt” als user interface, dan ben je eigenlijk verloren. Het biedt geen ondersteuning voor UTF-8. Zoals voorgesteld in de reacties en in het artikel is gekoppeld in de comments, moet u een Swing toepassing in plaats van te vertrouwen op de beperkte opdrachtprompt omgeving.

    • Bedankt voor dit antwoord. De gegevens die ik krijg, is in een Access-database, dus ik heb geen controle over hoe het oorspronkelijk is gecodeerd. Ik denk dat ik nodig heb om het te lezen en converteren naar het juiste formaat voor je iets doet. Ook proberen we te standaardiseren en gebruik van UTF-8 voor alles in onze applicatie. Is UTF-8 niet ondersteunen deze tekens?
    • U zou moeten instrueren van het JDBC-stuurprogramma en/of de database het gebruik van de juiste codering (degene die de database zelf gebruiken!). UTF-8 zeker ondersteunt deze personages, maar met een verschillende binaire representatie, als je begrijpt wat ik bedoel. Karakters zijn namelijk -zoals alles – overgedragen als bytes. Simpelweg omdat computers niet begrijpt iets anders. Dit artikel kunnen helpen in het begrijpen van het probleem onder de afzuigkappen.
    • Dank u voor de informatie en voor de link, dat is een groot artikel!
    • Ik ben weer terug met een andere vraag … moet ik niet in staat om te zetten rechtstreeks van de oorspronkelijke codering op UTF8? <code> String naam = “HANDICAP É ES”; String nameISO = new String(naam.getBytes(“CP850”), “ISO-8859-1”); String nameUTF8 = new String(naam.getBytes(“CP850”), “UTF8”); String nameUTF8_2 = new String(nameISO.getBytes(), “UTF8”); System.uit.println(“nameISO=” + nameISO); // werkt het Systeem.uit.println(“nameUTF8=” + nameUTF8); // werkt niet Systeem.uit.println(“nameUTF8=” + nameUTF8_2); // werkt < code> Natuurlijk begrijp ik nog steeds niet wat er “onder de motorkap”. Ik zal het opnieuw lezen van uw artikel nu.
    • Sorry mensen, ik probeerde verschillende keren om erachter te komen hoe de code in de juiste opmaak van de code…maar dat mislukte jammerlijk.
    • U moet bewaren en gebruiken de één en de dezelfde codering in alle lagen om te voorkomen dat de codering problemen. Je mag niet zetten van de ene naar de andere. Als de database bevat informatie codering X, dan moet je weergeven met codering X niet Y. Wanneer u het proces gebruiker ingangen, je moet verwerken met codering X niet Y. Als u de codering wijzigen, moet u deze wijzigen op alle lagen van de applicatie, ook de database.
    • Ook lees zorgvuldig de “Development Environment” deel in de aforelinked artikel. De Windows Command Console ondersteunt geen unicode. Gebruik Schommel of een IDE of schrijf naar tekstbestand.
    • Lieve BalusC, Dank u voor de bijgewerkte reactie. We WORDEN met een enkele coderings in onze applicatie, die is UTF8. Echter, zoals ik heb uitgelegd in een vorige reactie, we hebben geen controle over de creatie van de Access database bestand — we krijgen van een derde partij, en er is geen manier om ze op te lossen hun codering probleem. Dat is de reden waarom ik hebben om het te converteren van het gebroken codering in de Access-database naar UTF8, dat is wat de rest van onze applicatie gebruikt. Deze import van de Toegang tot DB, is de eerste stap in onze applicatie pijplijn.
    • Dan moet u het JDBC/ODBC-stuurprogramma bij gebruik van de DB-opgegeven codering voor het lezen en opslaan van gegevens en kruis de vingers (houden met UTF-8 in overblijfsel van de toepassing). Maar als de gegevens is reeds beschadigd is (te bekijken met behulp van de MS Access-programma), dan bent u verloren.

  3. 0

    Kunt u opgeven codering bij de vaststelling van de verbinding. Op deze manier was perfect en het oplossen van mijn codering probleem:

        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");

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *