Я заметил, что Internet Explorer 11 становится невероятно медленным, когда вырезаете данные, подобные jeremy. Это верно для Chrome, но у IE возникает проблема при передаче разрезанных данных в Blob-Constructor. На моей машине, передавая 5 МБ данных, происходит сбой в IE, а потребление памяти идет через крышу. Chrome быстро создает blob.
Запустите этот код для сравнения:
var byteArrays = [],
megaBytes = 2,
byteArray = new Uint8Array(megaBytes*1024*1024),
block,
blobSlowOnIE, blobFastOnIE,
i;
for (i = 0; i < (megaBytes*1024); i++) {
block = new Uint8Array(1024);
byteArrays.push(block);
}
//debugger;
console.profile("No Slices");
blobSlowOnIE = new Blob(byteArrays, { type: 'text/plain' });
console.profileEnd();
console.profile("Slices");
blobFastOnIE = new Blob([byteArray], { type: 'text/plain' });
console.profileEnd();
Поэтому я решил включить оба метода, описанные jeremy в одну функцию. Кредиты идут к нему за это.
function base64toBlob(base64Data, contentType, sliceSize) {
var byteCharacters,
byteArray,
byteNumbers,
blobData,
blob;
contentType = contentType || '';
byteCharacters = atob(base64Data);
// Get blob data sliced or not
blobData = sliceSize ? getBlobDataSliced() : getBlobDataAtOnce();
blob = new Blob(blobData, { type: contentType });
return blob;
/*
* Get blob data in one slice.
* => Fast in IE on new Blob(...)
*/
function getBlobDataAtOnce() {
byteNumbers = new Array(byteCharacters.length);
for (var i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
byteArray = new Uint8Array(byteNumbers);
return [byteArray];
}
/*
* Get blob data in multiple slices.
* => Slow in IE on new Blob(...)
*/
function getBlobDataSliced() {
var slice,
byteArrays = [];
for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
slice = byteCharacters.slice(offset, offset + sliceSize);
byteNumbers = new Array(slice.length);
for (var i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
byteArray = new Uint8Array(byteNumbers);
// Add slice
byteArrays.push(byteArray);
}
return byteArrays;
}
}
1) Указатели не являются массивами. Массивы не являются указателями. Не думайте о них так, потому что они разные. Как я могу это доказать? Подумайте, как они выглядят в памяти:
Наш массив arr
имеет длину 10 символов. Он содержит «Привет», но подождите, это еще не все! Поскольку у нас есть статически объявленный массив дольше, чем наше сообщение, мы получаем кучу NULL символов ('\0'
), брошенных бесплатно! Также обратите внимание на то, что имя arr
концептуально привязано к смежным символам (оно не указывает ни на что). [/g0]
Далее рассмотрим, как наш указатель будет выглядеть в памяти: [/g1] Обратите внимание, что мы указываем на массив символов в некотором месте в памяти только для чтения.
Таким образом, хотя оба arr
и ptr
были инициализированы одинаково, содержимое / местоположение каждого на самом деле различно.
Это ключевой момент: ptr - это переменная, мы можем указать ее на что угодно, arr - константа, она всегда будет ссылаться на этот блок из 10 символов.
2) []
является оператором «add and deference», который может использоваться по адресу. Это означает, что arr[0]
совпадает с *(arr+0)
. Итак, да, сделайте это:
printf("%c %c", *(arr+1), *(ptr+1));
Дает вам вывод «e e». Это не потому, что массивы являются указателями, потому что имя массива arr
и указатель ptr
оба передают вам адрес.
Ключевой пункт для # 2: Оператор deference *
и оператор add и deference []
не относятся к указателям и массивам соответственно. Эти операторы просто работают с адресами.
3) У меня нет очень простого ответа ... поэтому давайте забудем наши массивы символов на секунду и рассмотрим этот пример для Объяснение:
int b; //this is integer type
&b; //this is the address of the int b, right?
int c[]; //this is the array of ints
&c; //this would be the address of the array, right?
Итак, это довольно понятно, как об этом:
*c; //that's the first element in the array
Что говорит вам эта строка кода? Если я уважаю c
, тогда получаю int. Это означает, что просто c
- это адрес. Поскольку это начало массива, это адрес массива, а также адрес первого элемента в массиве, таким образом, с точки зрения значения:
c == &c;
4) Позвольте мне уйти тема для второго здесь ... этот последний вопрос является частью путаницы адресной арифметики. В какой-то момент я увидел вопрос о SO, подразумевающий, что адреса - это целые значения ... Вам нужно понять, что в адресах C есть знание типа. То есть:
iarr+1; //We added 1 to the address, so we moved 4 bytes
arr+1; //we added 1 to the address, so we moved 1 byte
В основном sizeof(int)
равно 4, а sizeof(char)
равно 1. Таким образом, «добавление 1 к массиву» не так просто, как кажется.
Итак, вернемся к вопросу, почему arr+1
отличается от &arr+1
? Первый добавляет 1 * sizeof(char)
= 1 к адресу, второй добавляет 1 * sizeof(arr)
= 10 к адресу.
Вот почему, хотя они оба «добавляют только 1», они дают разные результаты.
ptr
считается значением l». Нет, это не значит, чтоptr
считается lvalue i>; ведьarr
также считается lvalue i>. – CB Bailey 1 October 2012 в 16:46arr
иptr
являются lvalues i>, но так же каждое выражение является идентификатором, обозначающим переменную или ссылку. Это просто не похоже на обсуждение указателя и массива. – CB Bailey 1 October 2012 в 17:04