В Java, если у меня есть строка x
, как я могу вычислить количество байтов в этой строке?
В Java, если у меня есть строка x
, как я могу вычислить количество байтов в этой строке?
Ответы:
Строка - это список символов (т.е. кодовые точки). Количество байтов, взятых для представления строки, полностью зависит от того, какую кодировку вы используете, чтобы превратить ее в байты .
Тем не менее, вы можете превратить строку в байтовый массив, а затем посмотреть на его размер следующим образом:
// 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"
Итак, вы видите, что даже простая строка "ASCII" может иметь различное количество байтов в своем представлении, в зависимости от используемой кодировки. В качестве аргумента используйте любой набор символов, который вас интересует getBytes()
. И не попадайтесь в ловушку, предполагая, что UTF-8 представляет каждый символ как один байт, поскольку это также не так:
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 "????")
(Обратите внимание, что если вы не предоставите аргумент набора символов, будет использоваться набор символов платформы по умолчанию . Это может быть полезно в некоторых контекстах, но в целом следует избегать зависимости от значений по умолчанию и всегда использовать явный набор символов при кодировании / требуется расшифровка.)
getBytes()
его, будет использоваться кодировка символов по умолчанию вашей системы.
Если вы работаете с 64-битными ссылками:
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
Другими словами:
sizeof(string) = 36 + string.length() * 2
На 32-битной или 64-битной виртуальной машине со сжатыми OOP (-XX: + UseCompressedOops) ссылки имеют размер 4 байта. Таким образом, общее количество будет:
sizeof(string) = 32 + string.length() * 2
Это не учитывает ссылки на строковый объект.
sizeof
должно быть кратно 8.
Педантичный ответ (хотя не обязательно самый полезный, в зависимости от того, что вы хотите сделать с результатом):
string.length() * 2
Строки Java физически хранятся в UTF-16BE
кодировке, которая использует 2 байта на единицу кода и String.length()
измеряет длину в единицах кода UTF-16, так что это эквивалентно:
final byte[] utf16Bytes= string.getBytes("UTF-16BE");
System.out.println(utf16Bytes.length);
И это скажет вам размер внутреннего char
массива в байтах .
Примечание: "UTF-16"
даст другой результат, "UTF-16BE"
чем в предыдущей кодировке, которая вставит спецификацию , добавив 2 байта к длине массива.
В соответствии с Как преобразовать строки в и из байтовых массивов UTF8 в Java :
String s = "some text here";
byte[] b = s.getBytes("UTF-8");
System.out.println(b.length);
s.getBytes(Charset.forName("UTF-8"))
.
String
Экземпляр выделяет определенное количество байт в памяти. Может быть, вы смотрите на что-то вроде того, sizeof("Hello World")
что вернет число байтов, выделенных самой структурой данных?
В Java обычно нет необходимости в sizeof
функции, потому что мы никогда не выделяем память для хранения структуры данных. Мы можем взглянуть на String.java
файл для приблизительной оценки, и мы видим некоторые 'int', некоторые ссылки и a char[]
. Спецификация языка Java определяет, что char
диапазон составляет от 0 до 65535, поэтому двух байт достаточно для хранения одного символа в памяти. Но JVM не обязана хранить один символ в 2 байтах, она должна только гарантировать, что реализация char
может содержать значения в определенном диапазоне.
Так что sizeof
действительно не имеет никакого смысла в Java. Но, предполагая, что у нас есть большая строка и один char
выделяет два байта, тогда объем памяти String
объекта составляет по крайней мере 2 * str.length()
в байтах.
Есть метод getBytes () . Использовать его мудро .