Веб-платформа все чаще предлагает разработчикам инструменты, необходимые для создания отлаженных высокопроизводительных приложений для веба. В частности, WebAssembly (Wasm) открыла дверь быстрым и мощным веб-приложениям, а такие технологии, как Emscripten, теперь позволяют разработчикам повторно использовать проверенный и испытанный код в вебе. Чтобы по-настоящему использовать этот потенциал, разработчики должны иметь такую же мощность и гибкость, когда дело касается хранения.
Вот тут-то и появляется Storage Foundation API. Storage Foundation API — это новый быстрый и непредвзятый API хранилища, который открывает новые и востребованные варианты использования для веба, такие как реализация производительных баз данных и изящное управление большими временными файлами. С этим новым интерфейсом разработчики могут «принести свое собственное хранилище» в веб, сокращая разрыв между веб- и платформенно-специфичным кодом.
Storage Foundation API разработан так, чтобы напоминать очень простую файловую систему, поэтому он дает разработчикам гибкость, предоставляя общие, простые и производительные примитивы, на которых они могут создавать компоненты более высокого уровня. Приложения могут использовать лучший инструмент для своих нужд, находя правильный баланс между удобством использования, производительностью и надежностью.
Зачем Интернету нужен еще один API для хранения данных?
Веб-платформа предлагает разработчикам ряд вариантов хранения данных, каждый из которых создан с учетом конкретных вариантов использования.
- Некоторые из этих вариантов явно не пересекаются с этим предложением, поскольку они позволяют хранить только очень небольшие объемы данных, например, файлы cookie или API веб-хранилища, состоящий из механизмов
sessionStorage
иlocalStorage
. - Другие варианты уже устарели по разным причинам, например API файлов и записей каталогов или WebSQL .
- API доступа к файловой системе имеет похожую поверхность API, но его использование заключается в интерфейсе с файловой системой клиента и предоставлении доступа к данным, которые могут находиться вне собственности источника или даже браузера. Этот другой фокус сопровождается более строгими соображениями безопасности и более высокими затратами на производительность.
- IndexedDB API можно использовать в качестве бэкэнда для некоторых вариантов использования Storage Foundation API. Например, Emscripten включает IDBFS , постоянную файловую систему на основе IndexedDB. Однако, поскольку IndexedDB по сути является хранилищем ключ-значение, он имеет существенные ограничения производительности. Более того, прямой доступ к подразделам файла в IndexedDB еще сложнее и медленнее.
- Наконец, интерфейс CacheStorage широко поддерживается и настроен для хранения больших объемов данных, таких как ресурсы веб-приложений, но значения являются неизменяемыми.
Storage Foundation API — это попытка закрыть все пробелы предыдущих вариантов хранения, обеспечив эффективное хранение изменяемых больших файлов, определенных в источнике приложения.
Предлагаемые варианты использования API Storage Foundation
Примеры сайтов, которые могут использовать этот API:
- Приложения для производительности или творчества, которые работают с большими объемами видео, аудио или изображений. Такие приложения могут выгружать сегменты на диск вместо того, чтобы хранить их в памяти.
- Приложения, использующие постоянную файловую систему, доступную из Wasm, и которым требуется большая производительность, чем может гарантировать IDBFS.
Что такое API Storage Foundation?
API состоит из двух основных частей:
- Вызовы файловой системы , которые обеспечивают базовую функциональность для взаимодействия с файлами и путями к файлам.
- Дескрипторы файлов , которые обеспечивают доступ на чтение и запись к существующему файлу.
Вызовы файловой системы
API Storage Foundation представляет новый объект storageFoundation
, который находится в объекте window
и включает в себя ряд функций:
-
storageFoundation.open(name)
: открывает файл с указанным именем, если он существует, в противном случае создает новый файл. Возвращает обещание, которое разрешается с открытым файлом.
-
storageFoundation.delete(name)
: Удаляет файл с указанным именем. Возвращает обещание, которое разрешается при удалении файла. -
storageFoundation.rename(oldName, newName)
: Переименовывает файл со старого имени на новое имя атомарно. Возвращает обещание, которое разрешается при переименовании файла. -
storageFoundation.getAll()
: возвращает обещание, которое разрешается с помощью массива всех существующих имен файлов. -
storageFoundation.requestCapacity(requestedCapacity)
: запрашивает новую емкость (в байтах) для использования текущим контекстом выполнения. Возвращает обещание, которое было разрешено с оставшимся объемом доступной емкости.
-
storageFoundation.releaseCapacity(toBeReleasedCapacity)
: освобождает указанное количество байтов из текущего контекста выполнения и возвращает обещание, которое разрешается с оставшейся емкостью. -
storageFoundation.getRemainingCapacity()
: возвращает обещание, которое разрешается с доступной емкостью для текущего контекста выполнения.
Файловые дескрипторы
Работа с файлами происходит с помощью следующих функций:
-
NativeIOFile.close()
: закрывает файл и возвращает обещание, которое разрешается после завершения операции. -
NativeIOFile.flush()
: синхронизирует (то есть очищает) состояние файла в памяти с устройством хранения и возвращает обещание, которое разрешается после завершения операции.
-
NativeIOFile.getLength()
: возвращает обещание, которое разрешается с длиной файла в байтах. -
NativeIOFile.setLength(length)
: Устанавливает длину файла в байтах и возвращает обещание, которое разрешается после завершения операции. Если новая длина меньше текущей, байты удаляются, начиная с конца файла. В противном случае файл расширяется байтами с нулевым значением. NativeIOFile.read(buffer, offset)
: Считывает содержимое файла по указанному смещению через буфер, который является результатом передачи указанного буфера, который затем остается отсоединенным. ВозвращаетNativeIOReadResult
с переданным буфером и количеством байтов, которые были успешно прочитаны.NativeIOReadResult
— это объект, состоящий из двух записей:-
buffer
:ArrayBufferView
, который является результатом передачи буфера, переданного вread()
. Он имеет тот же тип и длину, что и исходный буфер. -
readBytes
: Количество байтов, которые были успешно считаны вbuffer
. Может быть меньше размера буфера, если произошла ошибка или если диапазон чтения выходит за пределы конца файла. Устанавливается в ноль, если диапазон чтения выходит за пределы конца файла.
-
NativeIOFile.write(buffer, offset)
: записывает содержимое указанного буфера в файл с указанным смещением. Буфер передается до записи любых данных и поэтому остается отсоединенным. ВозвращаетNativeIOWriteResult
с переданным буфером и количеством успешно записанных байтов. Файл будет расширен, если диапазон записи превысит его длину.NativeIOWriteResult
— это объект, состоящий из двух записей:-
buffer
:ArrayBufferView
, который является результатом передачи буфера, переданногоwrite()
. Он имеет тот же тип и длину, что и исходный буфер. -
writtenBytes
: Количество байтов, которые были успешно записаны вbuffer
. Может быть меньше размера буфера, если произошла ошибка.
-
Полные примеры
Чтобы сделать представленные выше концепции более понятными, приведем два полных примера, которые проведут вас по различным этапам жизненного цикла файлов Storage Foundation.
Открытие, письмо, чтение, закрытие
// Open a file (creating it if needed). const file = await storageFoundation.open('test_file'); try { // Request 100 bytes of capacity for this context. await storageFoundation.requestCapacity(100); const writeBuffer = new Uint8Array([64, 65, 66]); // Write the buffer at offset 0. After this operation, `result.buffer` // contains the transferred buffer and `result.writtenBytes` is 3, // the number of bytes written. `writeBuffer` is left detached. let result = await file.write(writeBuffer, 0); const readBuffer = new Uint8Array(3); // Read at offset 1. `result.buffer` contains the transferred buffer, // `result.readBytes` is 2, the number of bytes read. `readBuffer` is left // detached. result = await file.read(readBuffer, 1); // `Uint8Array(3) [65, 66, 0]` console.log(result.buffer); } finally { file.close(); }
Открытие, листинг, удаление
// Open three different files (creating them if needed). await storageFoundation.open('sunrise'); await storageFoundation.open('noon'); await storageFoundation.open('sunset'); // List all existing files. // `["sunset", "sunrise", "noon"]` await storageFoundation.getAll(); // Delete one of the three files. await storageFoundation.delete('noon'); // List all remaining existing files. // `["sunrise", "noon"]` await storageFoundation.getAll();
Демо
Вы можете поиграть с демо-версией API Storage Foundation в представленном ниже примере. Создавайте, переименовывайте, записывайте и читайте файлы, а также смотрите доступную емкость, которую вы запросили, обновляйте по мере внесения изменений. Исходный код демо-версии можно найти на Glitch.
Безопасность и разрешения
Команда Chromium разработала и реализовала API Storage Foundation, используя основные принципы, определенные в документе «Управление доступом к мощным функциям веб-платформы» , включая пользовательский контроль, прозрачность и эргономичность.
Следуя той же схеме, что и другие современные API-интерфейсы хранения в Интернете, доступ к API Storage Foundation привязан к источнику, что означает, что источник может получать доступ только к самостоятельно созданным данным. Он также ограничен безопасными контекстами.
Пользовательский контроль
Квота хранилища будет использоваться для распределения доступа к дисковому пространству и предотвращения злоупотреблений. Память, которую вы хотите занять, должна быть сначала запрошена. Как и другие API хранилища, пользователи могут очистить пространство, занимаемое API Storage Foundation, через свой браузер.
Полезные ссылки
- Публичный объяснитель
- Демонстрация API Storage Foundation | Исходный код демонстрации API Storage Foundation
- Ошибка отслеживания Chromium
- Запись ChromeStatus.com
- Компонент Blink:
Blink>Storage>NativeIO
- Обзор ТЭГа
- Намерение создать прототип
- Тема WebKit
- Тема Мозиллы
Благодарности
Storage Foundation API был разработан и реализован Эмануэлем Кривой и Ричардом Стотцем . Рецензентами этой статьи выступили Пит ЛеПейдж и Джо Медли .
Изображение героя предоставлено Маркусом Списке на Unsplash .