Подтвердить что ты не робот

Что такое метод HTML5 File.slice?

Я работаю с пользовательским API, чтобы позволить пользователю загружать файл (, надеюсь, произвольный размер). Если файл большой, он будет обмениваться файлами и обрабатываться несколькими запросами на сервере.

Я пишу код, который использует File и FileReader (HTML5) в соответствии со многими примерами из онлайн. В общем (из того, что я читал в Интернете) для передачи файла с файлом, люди сначала получат blob данных из своего файлового объекта

var file = $('input[type=file]')[0].files[0];
var blob = file.slice(start,end)

Затем используйте FileReader, чтобы прочитать blob readAsArrayBuffer(blob) или readAsBinaryString(blob)

И, наконец, в методе FileReader.onload(e) отправьте данные на сервер. Повторите этот процесс для всех фрагментов файла.

Мои вопросы

Зачем мне нужно использовать FileReader? Если я не использую его и просто отправлю капли с помощью File.slice, есть ли какая-либо гарантия, что операция разреза будет выполнена до того, как я попытаюсь отправить данные в каждом запросе. Объект File загружает весь файл при его создании (конечно же?). Обращается ли File.slice к позиции, заданной параметрами, а затем считывает информацию в? Документация не дает мне подсказки о том, как она реализована.

4b9b3361

Ответ 1

Важно помнить, что File наследует от Blob, File на самом деле не имеет метода среза, он получает этот метод из Blob. Файл просто добавляет несколько атрибутов метаданных.

Лучший способ думать о Blob (или файле) - это как указатель на данные, а не фактические данные. Похоже на дескриптор файла на других языках.

Фактически вы не можете получить данные в блоке без использования считывателя, который читает асинхронно, чтобы избежать блокировки потока пользовательского интерфейса.

Метод blob slice() просто возвращает другой Blob, но опять же, это не данные, это просто указатель на диапазон данных в исходном блоке, вроде как ограниченный указатель на представление. Чтобы фактически получить байты из нарезанного Blob, вам все равно нужно использовать читателя. В случае нарезанного блоба ваш читатель ограничен.

Это действительно просто предназначено для удобства, так что вам не нужно переносить кучу относительных и абсолютных смещений в вашем коде, вы можете просто получить ограниченный вид данных и использовать читателя так, как если бы вы были чтение из байта 0.

В случае XMLHttpRequest (при условии, что браузер поддерживает более новый интерфейс), данные будут передаваться по потоку и ограничены границами blob. В принципе, он будет работать так же, как вы могли бы подумать, что это сработает, если вы отправили указатель файла на метод потока (что в основном происходит под обложками). https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data#Sending_binary_data

По существу, это ленивый читатель. Если blob уже загружен/прочитан из файловой системы или был создан в памяти, он просто будет использовать это. Однако, когда вы используете файл, он будет лениво загружаться и транслироваться асинхронно из основного потока.

Основная логика заключается в том, что разработчики браузера никогда не хотят, чтобы чтение происходило синхронно, потому что оно могло блокировать основной поток, поэтому весь API был разработан вокруг этой основной философии. Обратите внимание, что Blob.slice() является синхронным - что вы знаете, что он фактически не выполняет IO, он просто настраивает границы и (возможно) указатели файлов.