У меня есть строка javascript размером около 500 КБ при отправке с сервера в UTF-8. Как я могу определить его размер в JavaScript?
Я знаю, что JavaScript использует UCS-2, значит это означает 2 байта на символ. Однако зависит ли это от реализации JavaScript? Или по кодировке страницы или, может быть, по типу содержимого?
javascript
string
size
byte
Пол Биггар
источник
источник
Ответы:
String
значения не зависят от реализации, согласно спецификации ECMA-262 3rd Edition , каждый символ представляет собой один 16-битный блок текста UTF-16 :источник
Эта функция вернет байтовый размер любой строки UTF-8, которую вы ей передали.
function byteCount(s) { return encodeURI(s).split(/%..|./).length - 1; }
Источник
Механизмы JavaScript могут использовать внутри себя UCS-2 или UTF-16. Большинство известных мне движков используют UTF-16, но какой бы выбор они ни выбрали, это всего лишь деталь реализации, которая не повлияет на характеристики языка.
Однако сам язык ECMAScript / JavaScript предоставляет символы в соответствии с UCS-2, а не UTF-16.
Источник
источник
.split(/%(?:u[0-9A-F]{2})?[0-9A-F]{2}|./)
Вместо этого используйте . Ваш фрагмент не работает для строк, которые кодируются как "% uXXXX".Если вы используете node.js, есть более простое решение с использованием буферов :
function getBinarySize(string) { return Buffer.byteLength(string, 'utf8'); }
Для этого есть библиотека npm: https://www.npmjs.org/package/utf8-binary-cutter (с уважением)
источник
Вы можете использовать Blob для получения размера строки в байтах.
Примеры:
console.info( new Blob(['😂']).size, // 4 new Blob(['👍']).size, // 4 new Blob(['😂👍']).size, // 8 new Blob(['👍😂']).size, // 8 new Blob(['I\'m a string']).size, // 12 // from Premasagar correction of Lauri's answer for // strings containing lone characters in the surrogate pair range: // https://stackoverflow.com/a/39488643/6225838 new Blob([String.fromCharCode(55555)]).size, // 3 new Blob([String.fromCharCode(55555, 57000)]).size // 4 (not 6) );
источник
Buffer.from('😂').length
Попробуйте эту комбинацию с использованием функции unescape js:
const byteAmount = unescape(encodeURIComponent(yourString)).length
Пример процесса полного кодирования:
const s = "1 a ф № @ ®"; //length is 11 const s2 = encodeURIComponent(s); //length is 41 const s3 = unescape(s2); //length is 15 [1-1,a-1,ф-2,№-3,@-1,®-2] const s4 = escape(s3); //length is 39 const s5 = decodeURIComponent(s4); //length is 11
источник
unescape
JavaScript устарела и не должна использоваться для декодирования универсальных идентификаторов ресурсов (URI). Источникunescape
он не используется для декодирования URI. Он используется для преобразования%xx
последовательностей в отдельные символы. AsencodeURIComponent
кодирует строку как UTF-8, представляя кодовые единицы либо как соответствующий ей символ ASCII, либо как%xx
последовательность,unescape(encodeURIComponent(...))
результатом вызова является двоичная строка, содержащая представление UTF-8 исходной строки..length
Правильный вызов дает размер в байтах строки, закодированной как UTF-8.un
)escape
устарел с 1999 года, но он по-прежнему доступен в каждом браузере ... - Тем не менее, есть веская причина отказаться от него. По сути, нет способа правильно их использовать (кроме кодирования / декодирования UTF8 в сочетании сen
- /decodeURI
(Component
) - или, по крайней мере, я не знаю другого полезного приложения для (un
)escape
). И сегодня есть лучшие альтернативы для кодирования / декодирования UTF8 (TextEncoder
и т. Д.)Обратите внимание, что если вы нацеливаетесь на node.js, вы можете использовать
Buffer.from(string).length
:var str = "\u2620"; // => "☠" str.length; // => 1 (character) Buffer.from(str).length // => 3 (bytes)
источник
UTF-8 кодирует символы, используя от 1 до 4 байтов на кодовую точку. Как указала CMS в принятом ответе, JavaScript будет хранить каждый символ внутри, используя 16 бит (2 байта).
Если вы анализируете каждый символ в строке с помощью цикла и подсчитываете количество байтов, используемых для каждой кодовой точки, а затем умножаете общее количество на 2, у вас должно быть использование памяти JavaScript в байтах для этой закодированной строки UTF-8. Возможно что-то вроде этого:
getStringMemorySize = function( _string ) { "use strict"; var codePoint , accum = 0 ; for( var stringIndex = 0, endOfString = _string.length; stringIndex < endOfString; stringIndex++ ) { codePoint = _string.charCodeAt( stringIndex ); if( codePoint < 0x100 ) { accum += 1; continue; } if( codePoint < 0x10000 ) { accum += 2; continue; } if( codePoint < 0x1000000 ) { accum += 3; } else { accum += 4; } } return accum * 2; }
Примеры:
getStringMemorySize( 'I' ); // 2 getStringMemorySize( '❤' ); // 4 getStringMemorySize( '𠀰' ); // 8 getStringMemorySize( 'I❤𠀰' ); // 14
источник
Я использую 3 способа:
TextEncoder ()
(new TextEncoder().encode("myString")).length)
Blob
new Blob(["myString"]).size)
Буфер
Buffer.byteLength("myString", 'utf8'))
источник
Размер строки JavaScript
Pre-ES6
Всегда 2 байта на символ. UTF-16 не допускается, потому что в спецификации сказано, что «значения должны быть 16-битными целыми числами без знака». Поскольку строки UTF-16 могут использовать 3- или 4-байтовые символы, это нарушит требование 2 байта. Важно отметить, что хотя UTF-16 не может полностью поддерживаться, стандарт требует, чтобы используемые двухбайтовые символы были действительными символами UTF-16. Другими словами, строки JavaScript до ES6 поддерживают подмножество символов UTF-16.
ES6 и более поздние версии
2 байта на символ или 5 или более байтов на символ. Дополнительные размеры вступают в игру, потому что ES6 (ECMAScript 6) добавляет поддержку экранирования кодовой точки Unicode . Использование escape-последовательности Unicode выглядит так: \ u {1D306}
Практические заметки
Это не относится к внутренней реализации конкретного движка. Например, некоторые движки используют структуры данных и библиотеки с полной поддержкой UTF-16, но то, что они предоставляют извне, не обязательно должно быть полной поддержкой UTF-16. Также движок может обеспечивать внешнюю поддержку UTF-16, но не обязан это делать.
Для ES6 практически говорящие символы никогда не будут длиннее 5 байтов (2 байта для точки перехода + 3 байта для кодовой точки Unicode), потому что последняя версия Unicode имеет только 136 755 возможных символов, что легко умещается в 3 байта. Однако это технически не ограничивается стандартом, поэтому в принципе один символ может использовать, скажем, 4 байта для кодовой точки и всего 6 байтов.
Большинство приведенных здесь примеров кода для расчета размера байта, похоже, не учитывают escape-последовательности кодовых точек ES6 Unicode, поэтому в некоторых случаях результаты могут быть неверными.
источник
Buffer.from('test').length
иBuffer.byteLength('test')
равен 4 (в Node) , аnew Blob(['test']).size
также равно 4?'\u{1F600}'.length===2
,'\u{1F600}'==='\uD83D\uDE00'
,'\u{1F600}'==='😀'
)Один элемент в строке JavaScript считается одной единицей кода UTF-16. Другими словами, символы String хранятся в 16-битном формате (1 единица кода), а 16-битный код равен 2 байтам (8-битный = 1 байт).
В
charCodeAt()
Метод может быть использован , чтобы возвращать целое число в диапазоне от 0 до 65535 , представляющего кода блока UTF-16 по данному индексу.В
codePointAt()
Может быть использовано , чтобы вернуть все значения точки коды для символов Unicode, например UTF-32.Когда символ UTF-16 не может быть представлен в одной 16-битной кодовой единице, он будет иметь суррогатную пару и, следовательно, использовать две кодовые единицы (2 x 16-битные = 4 байта)
См. Кодировки Unicode для получения информации о различных кодировках и их диапазонах кодов.
источник
Ответ Лаури Охерда хорошо работает для большинства строк, которые можно увидеть в дикой природе, но не удастся, если строка содержит одиночные символы в диапазоне суррогатных пар, от 0xD800 до 0xDFFF. Например
byteCount(String.fromCharCode(55555)) // URIError: URI malformed
Эта более длинная функция должна обрабатывать все строки:
function bytes (str) { var bytes=0, len=str.length, codePoint, next, i; for (i=0; i < len; i++) { codePoint = str.charCodeAt(i); // Lone surrogates cannot be passed to encodeURI if (codePoint >= 0xD800 && codePoint < 0xE000) { if (codePoint < 0xDC00 && i + 1 < len) { next = str.charCodeAt(i + 1); if (next >= 0xDC00 && next < 0xE000) { bytes += 4; i++; continue; } } } bytes += (codePoint < 0x80 ? 1 : (codePoint < 0x800 ? 2 : 3)); } return bytes; }
Например
bytes(String.fromCharCode(55555)) // 3
Он правильно рассчитает размер строк, содержащих суррогатные пары:
bytes(String.fromCharCode(55555, 57000)) // 4 (not 6)
Результаты можно сравнить со встроенной функцией Node
Buffer.byteLength
:Buffer.byteLength(String.fromCharCode(55555), 'utf8') // 3 Buffer.byteLength(String.fromCharCode(55555, 57000), 'utf8') // 4 (not 6)
источник
Я работаю со встроенной версией двигателя V8. Я тестировал одну строку. Толкаем каждый шаг 1000 знаков. UTF-8.
Первый тест с однобайтовым (8 бит, ANSI) символом «А» (шестнадцатеричный: 41). Второй тест с двухбайтовым символом (16 бит) «Ω» (шестнадцатеричный: CE A9) и третий тест с трехбайтовым символом (24 бит) «☺» (шестнадцатеричный: E2 98 BA).
Во всех трех случаях устройство распечатывает из памяти 888 000 знаков и использует ок. 26 348 кб в ОЗУ.
Результат: символы не сохраняются динамически. И не только с 16 бит. - Хорошо, возможно, только для моего случая (встроенное устройство ОЗУ 128 МБ, V8 Engine C ++ / QT). - Кодировка символов не имеет ничего общего с размером в оперативной памяти механизма javascript. Например, encodingURI и т. Д. Полезен только для передачи и хранения данных высокого уровня.
Встроенные или нет, но символы хранятся не только в 16-битном формате. К сожалению, у меня нет 100% ответа, что Javascript делает на низком уровне. Кстати. Я тестировал то же самое (первый тест выше) с массивом символа "A". Выталкивал 1000 предметов на каждом шагу. (Точно такой же тест. Просто заменила строку на массив) И система выявила нехватку памяти (требуется) после использования 10 416 КБ и длины массива 1 337 000. Итак, движок javascript не ограничен просто. Это немного сложнее.
источник
Вы можете попробовать это:
var b = str.match(/[^\x00-\xff]/g); return (str.length + (!b ? 0: b.length));
У меня это сработало.
источник