Можно использовать строку для представления тела HTTP-ответа и использовать размер для установки заголовка «Content-Length», который указывается в октетах / байтах, а не в символах. w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13
iX3
4
Столбец базы данных может иметь ограничение длины в байтах, например VARCHAR2 (4000 BYTE) в Oracle. Возможно, вы захотите узнать количество байтов строки в желаемой кодировке, чтобы узнать, подходит ли строка.
Сому
@ iX3 Точно так же, как я пытался сделать.
MC Emperor
1
Я полагаю, что есть два возможных толкования этого вопроса, в зависимости от цели: во-первых, «сколько памяти использует моя строка?». Ответ на этот вопрос предоставлен @roozbeh ниже (возможно, по модулю тонкостей ВМ, таких как сжатые OOPS). Другой - «если я преобразую строку в byte [], сколько памяти будет использовать этот байтовый массив?». На этот вопрос отвечает Анджей Дойл. Разница может быть большой: «Hello World» в UTF8 составляет 11 байтов, но String (на @roozbeh) составляет 50 байтов (если моя математика верна).
Л. Блан
Я должен был добавить, что 11 байтов не включают в себя служебные данные объекта byte [], который их содержит, поэтому сравнение несколько вводит в заблуждение.
Л. Блан
Ответы:
289
Строка - это список символов (т.е. кодовые точки). Количество байтов, взятых для представления строки, полностью зависит от того, какую кодировку вы используете, чтобы превратить ее в байты .
Тем не менее, вы можете превратить строку в байтовый массив, а затем посмотреть на его размер следующим образом:
// The input string for this testfinalString string ="Hello World";// Check length, in charactersSystem.out.println(string.length());// prints "11"// Check encoded sizesfinalbyte[] utf8Bytes = string.getBytes("UTF-8");System.out.println(utf8Bytes.length);// prints "11"finalbyte[] utf16Bytes= string.getBytes("UTF-16");System.out.println(utf16Bytes.length);// prints "24"finalbyte[] utf32Bytes = string.getBytes("UTF-32");System.out.println(utf32Bytes.length);// prints "44"finalbyte[] isoBytes = string.getBytes("ISO-8859-1");System.out.println(isoBytes.length);// prints "11"finalbyte[] winBytes = string.getBytes("CP1252");System.out.println(winBytes.length);// prints "11"
Итак, вы видите, что даже простая строка "ASCII" может иметь различное количество байтов в своем представлении, в зависимости от используемой кодировки. В качестве аргумента используйте любой набор символов, который вас интересует getBytes(). И не попадайтесь в ловушку, предполагая, что UTF-8 представляет каждый символ как один байт, поскольку это также не так:
finalString interesting ="\uF93D\uF936\uF949\uF942";// Chinese ideograms// Check length, in charactersSystem.out.println(interesting.length());// prints "4"// Check encoded sizesfinalbyte[] utf8Bytes = interesting.getBytes("UTF-8");System.out.println(utf8Bytes.length);// prints "12"finalbyte[] utf16Bytes= interesting.getBytes("UTF-16");System.out.println(utf16Bytes.length);// prints "10"finalbyte[] utf32Bytes = interesting.getBytes("UTF-32");System.out.println(utf32Bytes.length);// prints "16"finalbyte[] isoBytes = interesting.getBytes("ISO-8859-1");System.out.println(isoBytes.length);// prints "4" (probably encoded "????")finalbyte[] winBytes = interesting.getBytes("CP1252");System.out.println(winBytes.length);// prints "4" (probably encoded "????")
(Обратите внимание, что если вы не предоставите аргумент набора символов, будет использоваться набор символов платформы по умолчанию . Это может быть полезно в некоторых контекстах, но в целом следует избегать зависимости от значений по умолчанию и всегда использовать явный набор символов при кодировании / требуется расшифровка.)
И снова, если я использую getBytes (). Это даст мне такую же длину, как и x.length. Я ошибаюсь, потому что не уверен
Green
4
@Green Ash Длина байтового массива - getBytes () - и x.length МОЖЕТ быть равной, но это не гарантируется. Будет равным, если все символы представлены одним байтом каждый. Это всегда будет справедливо для кодировок символов, которые используют один байт на символ (или меньше), таких как ISO-8859-1. UTF-8 использует 1 или 2 байта, поэтому он зависит от точных символов в строке. Затем существуют кодировки символов, которые всегда используют два байта на символ.
Крис
Мне нравится ваш ответ :), так что они могут быть как-то одинаковыми, но не всегда я прав? хорошо, тогда можно использовать метод без параметра, потому что он вызывает ошибку !!
Зеленый
@ Зеленый смысл в том, что количество байтов не всегда совпадает с количеством символов . Количество байтов зависит от используемой кодировки символов. Вы должны будете знать, какую кодировку символов вы собираетесь использовать, и принять это во внимание. Какую ошибку вы получаете? Если вы просто используете getBytes()его, будет использоваться кодировка символов по умолчанию вашей системы.
Джеспер
1
@KorayTugay Да, более или менее. Вы можете поспорить о порядке причинно-следственных связей. Я был бы более склонен утверждать, что символ всегда 2 байта, потому что это примитивный тип данных, определенный как 2 байта шириной. (И что представление UTF-16 было главным образом следствием этого, а не наоборот.)
Анджей Дойл
63
Если вы работаете с 64-битными ссылками:
sizeof(string)=8+// object header used by the VM8+// 64-bit reference to char array (value)8+ string.length()*2+// character array itself (object header + 16-bit chars)4+// offset integer4+// count integer4+// cached hash code
Другими словами:
sizeof(string)=36+ string.length()*2
На 32-битной или 64-битной виртуальной машине со сжатыми OOP (-XX: + UseCompressedOops) ссылки имеют размер 4 байта. Таким образом, общее количество будет:
Я предполагал, что вопрос был о количестве байтов, выделенных в памяти для объекта String. Если вопрос касается количества байтов, необходимых для сериализации строки, как указали другие, это зависит от используемой кодировки.
roozbeh
2
Источник для твоего ответа? Спасибо
mavis
1
Примечание: sizeofдолжно быть кратно 8.
Дитер
19
Педантичный ответ (хотя не обязательно самый полезный, в зависимости от того, что вы хотите сделать с результатом):
string.length()*2
Строки Java физически хранятся в UTF-16BEкодировке, которая использует 2 байта на единицу кода и String.length()измеряет длину в единицах кода UTF-16, так что это эквивалентно:
но извините, когда я компилирую ваш код, это дает мне ошибку; из-за параметра "UTF-8". где, когда я передаю пустой параметр, он дает мне длину, такую же, как x.length. Я неправильно понимаю концепцию. помогите пожалуйста
Грин
@ Green Ash, какая у вас версия Java?
Бухаке Синди
@ Зеленый Эш, какое исключение ты получаешь?
Бухаке Синди
2
чтобы быть понятным, это вывод: test.java:11: незарегистрированное исключение java.io.UnsupportedEncodingException; должен быть перехвачен или объявлен как брошенный byte [] b = s.getBytes ("UTF-8"); ^ 1 ошибка Процесс завершен.
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()в байтах.
Мудро = не используйте тот без параметра набора символов.
Тило
Зачем? Это проблема, если я настраиваю свою среду для работы с кодировкой UTF8?
зигги
1
getBytes также создаст и скопирует массив байтов, поэтому, если вы говорите длинные строки, эта операция может стать дорогой.
ticktock
@ticktock, если ты все еще рядом, да, но какова альтернатива? Я пришел сюда в надежде на то, что библиотечная функция вернет нужное хранилище, чтобы я мог объединить его в больший объем.
SensorSmith
4
Попробуй это :
Bytes.toBytes(x).length
Предполагая, что вы объявили и инициализировали x раньше
Ответы:
Строка - это список символов (т.е. кодовые точки). Количество байтов, взятых для представления строки, полностью зависит от того, какую кодировку вы используете, чтобы превратить ее в байты .
Тем не менее, вы можете превратить строку в байтовый массив, а затем посмотреть на его размер следующим образом:
Итак, вы видите, что даже простая строка "ASCII" может иметь различное количество байтов в своем представлении, в зависимости от используемой кодировки. В качестве аргумента используйте любой набор символов, который вас интересует
getBytes()
. И не попадайтесь в ловушку, предполагая, что UTF-8 представляет каждый символ как один байт, поскольку это также не так:(Обратите внимание, что если вы не предоставите аргумент набора символов, будет использоваться набор символов платформы по умолчанию . Это может быть полезно в некоторых контекстах, но в целом следует избегать зависимости от значений по умолчанию и всегда использовать явный набор символов при кодировании / требуется расшифровка.)
источник
getBytes()
его, будет использоваться кодировка символов по умолчанию вашей системы.Если вы работаете с 64-битными ссылками:
Другими словами:
На 32-битной или 64-битной виртуальной машине со сжатыми OOP (-XX: + UseCompressedOops) ссылки имеют размер 4 байта. Таким образом, общее количество будет:
Это не учитывает ссылки на строковый объект.
источник
sizeof
должно быть кратно 8.Педантичный ответ (хотя не обязательно самый полезный, в зависимости от того, что вы хотите сделать с результатом):
Строки Java физически хранятся в
UTF-16BE
кодировке, которая использует 2 байта на единицу кода иString.length()
измеряет длину в единицах кода UTF-16, так что это эквивалентно:И это скажет вам размер внутреннего
char
массива в байтах .Примечание:
"UTF-16"
даст другой результат,"UTF-16BE"
чем в предыдущей кодировке, которая вставит спецификацию , добавив 2 байта к длине массива.источник
В соответствии с Как преобразовать строки в и из байтовых массивов UTF8 в Java :
источник
s.getBytes(Charset.forName("UTF-8"))
.String
Экземпляр выделяет определенное количество байт в памяти. Может быть, вы смотрите на что-то вроде того,sizeof("Hello World")
что вернет число байтов, выделенных самой структурой данных?В Java обычно нет необходимости в
sizeof
функции, потому что мы никогда не выделяем память для хранения структуры данных. Мы можем взглянуть наString.java
файл для приблизительной оценки, и мы видим некоторые 'int', некоторые ссылки и achar[]
. Спецификация языка Java определяет, чтоchar
диапазон составляет от 0 до 65535, поэтому двух байт достаточно для хранения одного символа в памяти. Но JVM не обязана хранить один символ в 2 байтах, она должна только гарантировать, что реализацияchar
может содержать значения в определенном диапазоне.Так что
sizeof
действительно не имеет никакого смысла в Java. Но, предполагая, что у нас есть большая строка и одинchar
выделяет два байта, тогда объем памятиString
объекта составляет по крайней мере2 * str.length()
в байтах.источник
Есть метод getBytes () . Использовать его мудро .
источник
Попробуй это :
Предполагая, что вы объявили и инициализировали x раньше
источник
Bytes
класс.Чтобы избежать попытки catch, используйте:
источник