210 votes

Octets d'une chaîne de caractères en Java

En Java, si j'ai une chaîne x comment puis-je calculer le nombre d'octets dans cette chaîne ?

19 votes

On peut vouloir utiliser une chaîne pour représenter le corps d'une réponse HTTP et utiliser la taille pour définir l'en-tête "Content-Length", qui est spécifié en octets/octets et non en caractères. w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13

4 votes

Une colonne de base de données peut avoir une restriction de longueur en octets, par exemple VARCHAR2 (4000 BYTE) dans Oracle. On peut vouloir connaître le nombre d'octets d'une chaîne de caractères dans l'encodage désiré pour savoir si la chaîne peut tenir.

0 votes

@iX3 Exactement la même chose que ce que j'essayais de faire.

326voto

Andrzej Doyle Points 52541

Une chaîne de caractères est une liste de caractères (c'est-à-dire les points de code). Le nombre d'octets nécessaires pour représenter la chaîne de caractères dépend entièrement de l'encodage que vous utilisez pour le transformer en octets. .

Cela dit, vous pouvez transformer la chaîne de caractères en un tableau d'octets, puis examiner sa taille comme suit :

// The input string for this test
final String string = "Hello World";

// Check length, in characters
System.out.println(string.length()); // prints "11"

// Check encoded sizes
final byte[] utf8Bytes = string.getBytes("UTF-8");
System.out.println(utf8Bytes.length); // prints "11"

final byte[] utf16Bytes= string.getBytes("UTF-16");
System.out.println(utf16Bytes.length); // prints "24"

final byte[] utf32Bytes = string.getBytes("UTF-32");
System.out.println(utf32Bytes.length); // prints "44"

final byte[] isoBytes = string.getBytes("ISO-8859-1");
System.out.println(isoBytes.length); // prints "11"

final byte[] winBytes = string.getBytes("CP1252");
System.out.println(winBytes.length); // prints "11"

Vous voyez donc que même une simple chaîne "ASCII" peut avoir un nombre différent d'octets dans sa représentation, selon l'encodage utilisé. Utilisez le jeu de caractères qui vous intéresse dans votre cas, en tant qu'argument de la fonction getBytes() . Et ne tombez pas dans le piège de supposer que UTF-8 représente chaque comme un seul octet, car ce n'est pas vrai non plus :

final String interesting = "\uF93D\uF936\uF949\uF942"; // Chinese ideograms

// Check length, in characters
System.out.println(interesting.length()); // prints "4"

// Check encoded sizes
final byte[] utf8Bytes = interesting.getBytes("UTF-8");
System.out.println(utf8Bytes.length); // prints "12"

final byte[] utf16Bytes= interesting.getBytes("UTF-16");
System.out.println(utf16Bytes.length); // prints "10"

final byte[] utf32Bytes = interesting.getBytes("UTF-32");
System.out.println(utf32Bytes.length); // prints "16"

final byte[] isoBytes = interesting.getBytes("ISO-8859-1");
System.out.println(isoBytes.length); // prints "4" (probably encoded "????")

final byte[] winBytes = interesting.getBytes("CP1252");
System.out.println(winBytes.length); // prints "4" (probably encoded "????")

(Notez que si vous ne fournissez pas d'argument pour le jeu de caractères, l'option jeu de caractères par défaut est utilisé. Cela peut être utile dans certains contextes, mais en général vous devriez éviter de dépendre des valeurs par défaut, et toujours utiliser un jeu de caractères explicite lorsque l'encodage/décodage est requis).

1 votes

Donc, si j'utilise getBytes(), cela me donnera la même longueur que x.length. Je me trompe parce que je ne suis pas sûr.

6 votes

@Cendre verte La longueur du tableau d'octets -- getBytes() -- et la longueur de x PEUVENT être égales mais ne sont pas garanties. Elle sera égale si tous les caractères sont représentés par un seul octet chacun. Cela sera toujours vrai pour les codages de caractères qui utilisent un seul octet par caractère (ou moins), comme ISO-8859-1. UTF-8 utilise soit 1 soit 2 octets, ce qui dépend donc des caractères exacts de la chaîne. Il existe également des codages de caractères qui utilisent toujours deux octets par caractère.

0 votes

J'aime votre réponse :) Donc, ils peuvent en quelque sorte être identiques, mais pas toujours, n'est-ce pas ? Alors, est-ce que je peux utiliser la méthode sans le paramètre, car cela me cause une erreur !

69voto

roozbeh Points 161

Si vous utilisez des références 64 bits :

sizeof(string) = 
8 + // object header used by the VM
8 + // 64-bit reference to char array (value)
8 + string.length() * 2 + // character array itself (object header + 16-bit chars)
4 + // offset integer
4 + // count integer
4 + // cached hash code

En d'autres termes :

sizeof(string) = 36 + string.length() * 2

Sur une VM 32 bits ou une VM 64 bits avec des OOPs compressées (-XX:+UseCompressedOops), les références sont de 4 octets. Donc le total serait :

sizeof(string) = 32 + string.length() * 2

Cela ne prend pas en compte les références à l'objet chaîne.

7 votes

Je supposais que la question portait sur le nombre d'octets alloués en mémoire pour un objet String. Si la question porte sur le nombre d'octets requis pour sérialiser la chaîne, comme d'autres l'ont souligné, cela dépend de l'encodage utilisé.

3 votes

Source de votre réponse ? Merci

1 votes

Note : sizeof doit être un multiple de 8.

19voto

Boris Pavlović Points 22207

Según Comment convertir des chaînes de caractères en tableaux d'octets UTF8 en Java ? :

String s = "some text here";
byte[] b = s.getBytes("UTF-8");
System.out.println(b.length);

0 votes

Mais excusez moi quand je compile votre code il me donne une erreur ; à cause du paramètre "UTF-8".où quand je passe un paramètre vide il me donne la même longueur que x.length. j'ai mal compris le concept. aidez moi svp

0 votes

@Cendre Verte, quelle version de Java avez-vous ?

0 votes

@Frêne Vert, quelle exception obtenez-vous ?

10voto

Andreas_D Points 64111

A String alloue une certaine quantité d'octets en mémoire. Peut-être que vous cherchez quelque chose comme sizeof("Hello World") qui renverrait le nombre d'octets alloués par la structure de données elle-même ?

En Java, il n'y a généralement pas besoin d'un fichier sizeof car nous n'allouons jamais de mémoire pour stocker une structure de données. Nous pouvons jeter un coup d'œil à la String.java pour une estimation approximative, et nous voyons quelques 'int', quelques références et un char[] . Le site Spécification du langage Java définit, qu'une char va de 0 à 65535, donc deux octets sont suffisants pour garder un seul caractère en mémoire. Mais une JVM n'est pas obligée de stocker un caractère dans 2 octets, elle doit seulement garantir que l'implémentation de la fonction char peut contenir des valeurs de l'intervalle défini.

Alors sizeof n'a vraiment aucun sens en Java. Mais, en supposant que nous ayons un grand String et un char alloue deux octets, alors l'empreinte mémoire d'une String est au moins 2 * str.length() en octets.

8voto

Andrei Ciobanu Points 3517

Il y a une méthode appelée getBytes() . Utilisez-le à bon escient.

20 votes

A bon escient = n'utilisez pas celui qui n'a pas de paramètre de jeu de caractères.

0 votes

Pourquoi ? Est-ce un problème si je configure mon environnement pour fonctionner avec un encodage UTF8 ?

2 votes

GetBytes va également créer et copier le tableau d'octets, donc si vous parlez de longues chaînes de caractères, cette opération peut devenir coûteuse.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X