Comment convertir des chaînes de caractères vers et à partir de tableaux d'octets UTF8 en Java

StackOverflow https://stackoverflow.com/questions/88838

Question

En Java, j'ai une chaîne et je veux l'encoder sous forme de tableau d'octets (en UTF8 ou autre). Alternativement, j'ai un tableau d'octets (dans certains codages connus) et je veux le convertir en une chaîne Java. Comment puis-je effectuer ces conversions?

Était-ce utile?

La solution

Convertir de chaîne en octet []:

String s = "some text here";
byte[] b = s.getBytes(StandardCharsets.UTF_8);

Conversion d'octet [] en chaîne:

byte[] b = {(byte) 99, (byte)97, (byte)116};
String s = new String(b, StandardCharsets.US_ASCII);

Vous devez bien sûr utiliser le nom de codage correct. Mes exemples utilisent US-ASCII et UTF-8, les deux encodages les plus courants.

Autres conseils

Voici une solution qui évite d'effectuer la recherche de jeu de caractères à chaque conversion:

import java.nio.charset.Charset;

private final Charset UTF8_CHARSET = Charset.forName("UTF-8");

String decodeUTF8(byte[] bytes) {
    return new String(bytes, UTF8_CHARSET);
}

byte[] encodeUTF8(String string) {
    return string.getBytes(UTF8_CHARSET);
}
String original = "hello world";
byte[] utf8Bytes = original.getBytes("UTF-8");

Vous pouvez convertir directement via String (octet). [], String) constructeur et méthode getBytes (String). Java expose les jeux de caractères disponibles via le Jeu de caractères classe. La documentation JDK répertorie les codages pris en charge . .

90% du temps, de telles conversions sont effectuées sur des flux, vous utiliserez donc Lecteur / Writer . Vous ne décoderiez pas de manière incrémentielle à l'aide des méthodes String sur des flux d'octets arbitraires. Vous vous laisseriez ouvert aux bogues impliquant des caractères multi-octets.

Mon implémentation tomcat7 accepte les chaînes au format ISO-8859-1; malgré le type de contenu de la requête HTTP. La solution suivante a fonctionné pour moi lorsque j'essaie d'interpréter correctement des caractères tels que '& # 233;' .

byte[] b1 = szP1.getBytes("ISO-8859-1");
System.out.println(b1.toString());

String szUT8 = new String(b1, "UTF-8");
System.out.println(szUT8);

Lors de la tentative d'interprétation de la chaîne au format US-ASCII, les informations d'octet n'étaient pas interprétées correctement.

b1 = szP1.getBytes("US-ASCII");
System.out.println(b1.toString());

Comme alternative, StringUtils d'Apache Commons peut être utilisé.

 byte[] bytes = {(byte) 1};
 String convertedString = StringUtils.newStringUtf8(bytes);

ou

 String myString = "example";
 byte[] convertedBytes = StringUtils.getBytesUtf8(myString);

Si vous avez un jeu de caractères non standard, vous pouvez utiliser getBytesUnchecked () ou newString () en conséquence.

Pour décoder une série d'octets en un message de chaîne normale, je l'ai finalement obtenu avec l'encodage UTF-8 avec ce code:

/* Convert a list of UTF-8 numbers to a normal String
 * Usefull for decoding a jms message that is delivered as a sequence of bytes instead of plain text
 */
public String convertUtf8NumbersToString(String[] numbers){
    int length = numbers.length;
    byte[] data = new byte[length];

    for(int i = 0; i< length; i++){
        data[i] = Byte.parseByte(numbers[i]);
    }
    return new String(data, Charset.forName("UTF-8"));
}

Si vous utilisez ASCII 7 bits ou ISO-8859-1 (un format étonnamment commun), vous n'avez pas besoin de créer un nouveau java.lang.String du tout. Il est beaucoup plus performant de simplement convertir l'octet en caractère:

Exemple de travail complet:

for (byte b : new byte[] { 43, 45, (byte) 215, (byte) 247 }) {
    char c = (char) b;
    System.out.print(c);
}

Si vous n'utilisez pas des caractères étendus tels que & # 196 ;, & # 198 ;, & # 197 ;, & # 199 ;, & # 207; , & # 202; et peuvent être sûrs que les seules valeurs transmises sont celles des 128 premiers caractères Unicode. Ce code fonctionnera également pour UTF-8 et ASCII étendu (comme cp-1252).

//query is your json   

 DefaultHttpClient httpClient = new DefaultHttpClient();
 HttpPost postRequest = new HttpPost("http://my.site/test/v1/product/search?qy=");

 StringEntity input = new StringEntity(query, "UTF-8");
 input.setContentType("application/json");
 postRequest.setEntity(input);   
 HttpResponse response=response = httpClient.execute(postRequest);

Je ne peux pas commenter mais je ne veux pas créer un nouveau fil de discussion. Mais ça ne marche pas. Un aller simple:

byte[] b = new byte[]{ 0, 0, 0, -127 };  // 0x00000081
String s = new String(b,StandardCharsets.UTF_8); // UTF8 = 0x0000, 0x0000,  0x0000, 0xfffd
b = s.getBytes(StandardCharsets.UTF_8); // [0, 0, 0, -17, -65, -67] 0x000000efbfbd != 0x00000081

J'aurais besoin de b [] le même tableau avant et après le codage, ce qui n'est pas le cas (cela renvoie à la première réponse).

Charset UTF8_CHARSET = Charset.forName("UTF-8");
String strISO = "{\"name\":\"א\"}";
System.out.println(strISO);
byte[] b = strISO.getBytes();
for (byte c: b) {
    System.out.print("[" + c + "]");
}
String str = new String(b, UTF8_CHARSET);
System.out.println(str);
Reader reader = new BufferedReader(
    new InputStreamReader(
        new ByteArrayInputStream(
            string.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8));

terriblement tard, mais je viens de rencontrer ce problème et ceci est ma solution:

private static String removeNonUtf8CompliantCharacters( final String inString ) {
    if (null == inString ) return null;
    byte[] byteArr = inString.getBytes();
    for ( int i=0; i < byteArr.length; i++ ) {
        byte ch= byteArr[i]; 
        // remove any characters outside the valid UTF-8 range as well as all control characters
        // except tabs and new lines
        if ( !( (ch > 31 && ch < 253 ) || ch == '\t' || ch == '\n' || ch == '\r') ) {
            byteArr[i]=' ';
        }
    }
    return new String( byteArr );
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top