2009-09-23 11 views
3

Existe-t-il un moyen de convertir une chaîne ANSI en UTF à l'aide de Java.Conversion de caractères ANSI en UTF-8 en Java

J'ai un sérialiseur personnalisé qui utilise readUTF & méthodes writeUTF de la classe DataInputStream pour désérialiser et sérialiser la chaîne. Si je reçois une chaîne codée en ANSI et est trop longue, ~ 100000 caractères longs j'obtiens l'erreur;

Causée par: java.io.UTFDataFormatException: trop longue chaîne codée: 106958 octets

Cependant, dans mes tests JUnit je suis en mesure de créer une chaîne avec 120000 « a 'et fonctionne parfaitement

J'ai vérifié les messages suivants, mais j'ai toujours des erreurs;

+0

Voulez-vous dire ASCII? Si c'est le cas, il est déjà en UTF-8 - pourriez-vous expliquer un peu plus. Afficher les erreurs, etc. – Mark

+3

Non ANSI! = ASCII. ANSI est une collection complète de pages de code. –

+0

en raison de restrictions de taille sur readUTF et writeUTF j'ai modifié mon sérialiseur envoyer le texte en parties – n002213f

Répondre

6

Cette erreur n'est pas due au codage de caractères. Cela signifie que la longueur des données UTF est erronée.

EDIT: Je viens de réaliser qu'il s'agit d'une erreur d'écriture, pas d'erreur de lecture.

La longueur UTF est de seulement 2 octets, elle ne peut donc contenir que 64 octets UTF-8. Vous essayez d'écrire 100K, ça ne va pas fonctionner.

Cette limite est hardcoded et aucun moyen de contourner ce problème,

if (utflen > 65535) 
    throw new UTFDataFormatException(
      "encoded string too long: " + utflen + " bytes"); 
+0

Intéressant, mais pourquoi passer tous mes tests avec plus de caractères? – n002213f

+0

Vous devez me montrer vos cas de test. Ils ont tort. Voir mes modifications. –

+0

J'ai utilisé le code suivant pour générer la chaîne de test; StringBuffer sb2 = new StringBuffer(); Pour (int i = 0; i <120000; i ++) \t \t} \t \t Chaîne longString2 = sb2.toString(); – n002213f

3
byte[] asciiBytes = ...; 
String unicode = new String(asciiBytes, "US-ASCII"); 
byte[] utfBytes = unicode.getBytes("UTF-8"); 
+0

Il semble que j'ai mal lu la question originale concernant ASCII vs. ANSI, et avec les dernières modifications de question, ma réponse n'est pas vraiment pertinente. – iammichael

2

qui ANSI codepage? Il y a beaucoup de codages de caractères différents qui se réfèrent tous à "ANSI". La page de codes DOS est 437 (sans les symboles de dessin). Si vous utilisez 850 codepage, cela fonctionne:

String unicode = new String(bytes, "IBM850"); 

(où bytes est un tableau avec les caractères ANSI). Après cela, vous pouvez convertir cette chaîne en un tableau d'octets avec n'importe quel codage en utilisant unicode.getBytes(encoding).

Windows utilise souvent la page de codes 1252 (utilisez "windows-1252" pour cela).

+0

essayé, mais ne fonctionne pas, je reçois la même erreur.Y at-il un moyen de vérifier l'encodage dans une chaîne afin que je puisse être sûr de son ANSI? – n002213f

+0

cela va convertir ANSI à partir de telnet, comme un jeu de boue, à une chaîne "régulière"? – Thufir

+0

Cela convertira les octets de n'importe quelle source en une chaîne Unicode. Mais pour qu'il fonctionne correctement, vous devez savoir exactement quel encodage utilise la source. Peu importe s'il s'agit d'un fichier, d'un service distant ou d'un périphérique matériel. –

1

ZZ Coder déjà répondu à la question, mais j'ai écrit une explication plus détaillée et en proposant une solution de contournement sur this blog. Fondamentalement, le problème est dans DataOutputStream, car il restreint la chaîne accessible en écriture à 64 Ko. Il existe d'autres solutions possibles pour contourner le problème, certains peuvent fonctionner sans casser le format de données binaire réel que l'on utilise ...