En Java, si j'ai une chaîne x
, comment puis-je calculer le nombre d'octets dans cette chaîne?
En Java, si j'ai une chaîne x
, comment puis-je calculer le nombre d'octets dans cette chaîne?
Réponses:
Une chaîne est une liste de caractères (c'est-à-dire des points de code). Le nombre d'octets pris pour représenter la chaîne dépend entièrement du codage que vous utilisez pour la transformer en octets .
Cela dit, vous pouvez transformer la chaîne 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"
Ainsi vous voyez, même une simple chaîne "ASCII" peut avoir un nombre d'octets différent dans sa représentation, selon le codage utilisé. Utilisez le jeu de caractères qui vous intéresse pour votre cas, comme argument getBytes()
. Et ne tombez pas dans le piège de supposer que UTF-8 représente chaque caractère 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 de jeu de caractères, le jeu de caractères par défaut de la plate-forme est utilisé. Cela peut être utile dans certains contextes, mais en général, vous devez éviter de dépendre des valeurs par défaut et toujours utiliser un jeu de caractères explicite lors de l'encodage / le décodage est nécessaire.)
getBytes()
il utilisera le codage de caractères par défaut de votre système.
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 machine virtuelle 32 bits ou une machine virtuelle 64 bits avec des POO compressés (-XX: + UseCompressedOops), les références sont de 4 octets. Le total serait donc:
sizeof(string) = 32 + string.length() * 2
Cela ne prend pas en compte les références à l'objet string.
sizeof
doit être multiple de 8.
La réponse pédante (mais pas nécessairement la plus utile, selon ce que vous voulez faire du résultat) est:
string.length() * 2
Les chaînes Java sont physiquement stockées dans l' UTF-16BE
encodage, qui utilise 2 octets par unité de code, et String.length()
mesure la longueur en unités de code UTF-16, donc cela équivaut à:
final byte[] utf16Bytes= string.getBytes("UTF-16BE");
System.out.println(utf16Bytes.length);
Et cela vous indiquera la taille du char
tableau interne , en octets .
Remarque: "UTF-16"
donnera un résultat différent de celui "UTF-16BE"
que l'ancien encodage insérera une nomenclature , ajoutant 2 octets à la longueur du tableau.
Selon Comment convertir des chaînes vers et depuis des tableaux d'octets UTF8 en Java :
String s = "some text here";
byte[] b = s.getBytes("UTF-8");
System.out.println(b.length);
s.getBytes(Charset.forName("UTF-8"))
.
Une String
instance alloue une certaine quantité d'octets en mémoire. Peut-être cherchez-vous quelque chose comme sizeof("Hello World")
qui retournerait 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 de sizeof
fonction, car nous n'allouons jamais de mémoire pour stocker une structure de données. Nous pouvons jeter un oeil au String.java
fichier pour une estimation approximative, et nous voyons des 'int', des références et un char[]
. La spécification du langage Java définit que a char
va de 0 à 65535, donc deux octets suffisent pour garder un seul caractère en mémoire. Mais une JVM n'a pas besoin de stocker un caractère sur 2 octets, elle doit seulement garantir que l'implémentation de char
peut contenir les valeurs de la plage de définition.
Cela sizeof
n'a donc vraiment aucun sens en Java. Mais, en supposant que nous avons une grande chaîne et que l'on char
alloue deux octets, alors l'empreinte mémoire d'un String
objet est au moins 2 * str.length()
en octets.
Il existe une méthode appelée getBytes () . Fais-en bon usage .