Якщо у Java є String x
, як я можу обчислити кількість байтів у цьому рядку?
Якщо у Java є String 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-розрядний VM або 64-бітний VM із стиснутими OOP (-XX: + UseCompressionOops) посилання складають 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"
оскільки колишнє кодування вставить BOM , додавши 2 байти до довжини масиву.
Відповідно до того, як перетворити рядки в байтові масиви UTF8 та з них :
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. Але, якщо припустити, що у нас є велика String і один char
виділяє два байти, то слід пам'яті String
об’єкта знаходиться принаймні 2 * str.length()
в байтах.
Існує метод під назвою getBytes () . Використовуйте його розумно.