Spec-Zone.ru › Cordova 8

cordova-plugin-file

Этот плагин реализует API File, позволяющий читать и записывать файлы, находящиеся на устройстве.

Этот плагин основан на нескольких спецификациях, включая: API File HTML5 http://www.w3.org/TR/FileAPI/

Директории и расширения системы Последняя версия: http://www.w3.org/TR/2012/WD-file-system-api-20120417/ Хотя большая часть кода плагина была написана, когда действовала более ранняя спецификация: http://www.w3.org/TR/2011/WD-file-system-api-20110419/

Он также реализует спецификацию FileWriter: http://dev.w3.org/2009/dap/file-system/file-writer.html

Примечание. Хотя спецификация W3C FileSystem устарела для веб-браузеров, API FileSystem поддерживаются в приложениях Cordova с помощью этого плагина для платформ, перечисленных в списке Поддерживаемые платформы, за исключением платформы Browser.

Чтобы получить несколько идей о том, как использовать плагин, ознакомьтесь с примером в нижней части этой страницы. Для дополнительных примеров (ориентированных на браузер) см. статью о системе файлов HTML5 Rocks' FileSystem article.

Для обзора других вариантов хранения см. руководство по хранению Cordova's storage guide.

Этот плагин определяет глобальный cordova.file объект.

Несмотря на то, что он находится в глобальной области видимости, он недоступен до события deviceready.

document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
    console.log(cordova.file);
}

Сообщайте о проблемах на форуме отслеживания проблем Apache Cordova

Установка

cordova plugin add cordova-plugin-file

Поддерживаемые платформы

  • Android
  • iOS
  • OS X
  • Windows*
  • Браузер

* Эти платформы не поддерживают FileReader.readAsArrayBuffer ни FileWriter.write(blob).

Куда хранить файлы

Начиная с версии 1.2.0, предоставляются URL важных каталогов файловой системы. Каждый URL имеет вид file:///path/to/spot/ и может быть преобразован в DirectoryEntry с помощью window.resolveLocalFileSystemURL().

  • cordova.file.applicationDirectory - Только для чтения каталог, в котором установлено приложение. (iOS, Android, BlackBerry 10, OSX, windows)

  • cordova.file.applicationStorageDirectory - Корневой каталог песочницы приложения; в iOS и windows это местоположение только для чтения (но определенные подкаталоги [например, /Documents в iOS или /localState в windows] доступны для чтения и записи). Все данные в нём приватны для приложения. (iOS, Android, BlackBerry 10, OSX)

  • cordova.file.dataDirectory - Постоянное и приватное хранилище данных внутри песочницы приложения с использованием внутренней памяти (в Android, если вам нужно использовать внешнюю память, используйте .externalDataDirectory). В iOS этот каталог не синхронизируется с iCloud (используйте .syncedDataDirectory). (iOS, Android, BlackBerry 10, windows)

  • cordova.file.cacheDirectory - Каталог для кэшированных файлов данных или любых файлов, которые ваше приложение может легко воссоздать. ОС может удалять эти файлы, когда на устройстве заканчивается место, но приложения не должны полагаться на ОС для удаления файлов здесь.

  • cordova.file.externalApplicationStorageDirectory - Пространство приложения на внешнем хранилище. (Android)

  • cordova.file.externalDataDirectory - Куда помещать файлы данных, специфичные для приложения, на внешнем хранилище. (Android)

  • cordova.file.externalCacheDirectory - Кэш приложения на внешнем хранилище. (Android)

  • cordova.file.externalRootDirectory - Корень внешнего хранилища (карты SD). (Android, BlackBerry 10)

  • cordova.file.tempDirectory - Временный каталог, который ОС может очищать по своему усмотрению. Не полагайтесь на ОС для очистки этого каталога; ваше приложение должно всегда удалять файлы по мере необходимости.

  • cordova.file.syncedDataDirectory - Хранит файлы, специфичные для приложения, которые должны быть синхронизированы (например, с iCloud). (iOS, windows)

  • cordova.file.documentsDirectory - Файлы, приватные для приложения, но важные для других приложений (например, файлы Office). Обратите внимание, что для OSX это каталог пользователя ~/Documents. (iOS, OSX)

  • cordova.file.sharedDirectory - Файлы, доступные всем приложениям в целом. (BlackBerry 10)

Макеты файловой системы

Хотя технически это деталь реализации, очень полезно знать, как свойства cordova.file.* отображаются на физических путях реального устройства.

Макет файловой системы iOS

Путь устройства cordova.file.* iosExtraFileSystems чтение/запись? постоянно? Очищается ОС? синхронизация приватный?
/var/mobile/Applications/<UUID>/ applicationStorageDirectory - чтение нет данных нет данных нет данных Да
appname.app/ applicationDirectory bundle чтение нет данных нет данных нет данных Да
www/ - - чтение нет данных нет данных нет данных Да
Documents/ documentsDirectory documents чтение/запись Да Нет Да Да
NoCloud/ - documents-nosync чтение/запись Да Нет Нет Да
Library - library чтение/запись Да Нет Возможно да? Да
NoCloud/ dataDirectory library-nosync чтение/запись Да Нет Нет Да
Cloud/ syncedDataDirectory - чтение/запись Да Нет Да Да
Caches/ cacheDirectory cache чтение/запись Да* Да*** Нет Да
tmp/ tempDirectory - чтение/запись Нет** Да*** Нет Да

* Файлы сохраняются при перезапусках и обновлениях приложения, но этот каталог может очищаться в любое время по желанию ОС. Ваше приложение должно уметь воссоздавать любое удалённое содержимое.

** Файлы могут сохраняться при перезапусках приложения, но не полагайтесь на это поведение. Файлы не гарантируют сохранения при обновлениях. Ваше приложение должно удалять файлы из этого каталога, когда это применимо, так как ОС не гарантирует, когда (или даже если) эти файлы будут удалены.

*** ОС может очищать содержимое этого каталога, когда посчитает это необходимым, но не полагайтесь на это. Вы должны очищать этот каталог, как это нужно вашему приложению.

Макет файловой системы Android

Путь к устройству cordova.file.* AndroidExtraFileSystems Чтение/запись? Постоянное хранение? Очистка ОС Приватное?
file:///android_asset/ applicationDirectory assets r N/A N/A Да
/data/data/<app-id>/ applicationStorageDirectory - r/w N/A N/A Да
cache cacheDirectory cache r/w Да Да* Да
files dataDirectory files r/w Да Нет Да
Documents documents r/w Да Нет Да
<sdcard>/ externalRootDirectory sdcard r/w Да Нет Нет
Android/data/<app-id>/ externalApplicationStorageDirectory - r/w Да Нет Нет
cache externalCacheDirectory cache-external r/w Да Нет** Нет
files externalDataDirectory files-external r/w Да Нет Нет

* ОС может периодически очищать этот каталог, но не полагайтесь на это поведение. Очищайте содержимое этого каталога соответствующим образом для вашего приложения. Если пользователь вручную очистит кэш, содержимое этого каталога удаляется.

** ОС не очищает этот каталог автоматически; вы несете ответственность за управление содержимым самостоятельно. Если пользователь вручную очистит кэш, содержимое каталога удаляется.

Примечание: Если внешний накопитель не может быть смонтирован, свойства cordova.file.external* являются null.

Макет файловой системы OS X

Путь к устройству cordova.file.* iosExtraFileSystems Чтение/запись? Очистка ОС Приватное?
/Applications/<appname>.app/ - bundle r N/A Да
Content/Resources/ applicationDirectory - r N/A Да
~/Library/Application Support/<bundle-id>/ applicationStorageDirectory - r/w Нет Да
files/ dataDirectory - r/w Нет Да
~/Documents/ documentsDirectory documents r/w Нет Нет
~/Library/Caches/<bundle-id>/ cacheDirectory cache r/w Нет Да
/tmp/ tempDirectory - r/w Да* Да
/ rootDirectory root r/w Нет** Нет

Примечание: Это макет для приложений, не использующих режим песочницы. Если вы включите режим песочницы, applicationStorageDirectory будут расположены ниже ~/Library/Containers/<bundle-id>/Data/Library/Application Support.

* Файлы сохраняются при перезапуске и обновлении приложения, но этот каталог может быть очищен ОС в любое время. Ваше приложение должно уметь восстанавливать любые данные, которые могут быть удалены. Вы должны очищать этот каталог соответствующим образом для вашего приложения.

** Предоставляет доступ ко всей файловой системе. Доступно только для приложений, не использующих режим песочницы.

Макет файловой системы Windows

Путь к устройству cordova.file.* Чтение/запись? Постоянное хранение? Очистка ОС Приватное?
ms-appdata:/// applicationDirectory r N/A N/A Да
local/ dataDirectory r/w Да Нет Да
temp/ cacheDirectory r/w Нет Да* Да
temp/ tempDirectory r/w Нет Да* Да
roaming/ syncedDataDirectory r/w Да Нет Да

* ОС может периодически очищать этот каталог

Особенности Android

Местоположение постоянного хранилища Android

Существует несколько допустимых мест для хранения постоянных файлов на устройстве Android. См. эту страницу для подробного обсуждения различных возможностей.

Предыдущие версии плагина выбирали местоположение временных и постоянных файлов при запуске, в зависимости от того, утверждало ли устройство, что карта SD (или эквивалентный раздел хранения) смонтирована. Если карта SD была смонтирована, или если был доступен большой раздел внутреннего хранилища (например, на устройствах Nexus), то постоянные файлы хранились в корневом каталоге этого пространства. Это означало, что все приложения Cordova могли видеть все файлы, доступные на карте.

Если карта SD не была доступна, то предыдущие версии хранили данные в /data/data/<packageId>, что изолирует приложения друг от друга, но может привести к совместному использованию данных между пользователями.

Теперь можно выбрать, хранить ли файлы во внутреннем хранилище или использовать предыдущую логику, с предпочтением в файле конфигурации вашего приложения (config.xml). Для этого добавьте одну из этих двух строк в config.xml:

<preference name="AndroidPersistentFileLocation" value="Internal" />

<preference name="AndroidPersistentFileLocation" value="Compatibility" />

Без этой строки плагин File будет использовать Internal в качестве значения по умолчанию. Если тег предпочтения присутствует, и не является одним из этих значений, приложение не запустится.

Если ваше приложение уже было выпущено пользователям с использованием более старой (до 3.0.0) версии этого плагина и хранило файлы в постоянной файловой системе, то вы должны установить предпочтение в Compatibility , если в вашем config.xml нет указания местоположения для постоянной файловой системы. Переключение на расположение "Внутреннее" может означать, что существующие пользователи, которые обновят свое приложение, возможно, не смогут получить доступ к своим ранее сохранённым файлам, в зависимости от их устройства.

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

Медленные рекурсивные операции для /android_asset

Перечисление каталогов активов очень медленно на Android. Вы можете ускорить его, добавив src/android/build-extras.gradle в корень вашего проекта Android (также требуется cordova-android@4.0.0 или выше).

Разрешение на запись во внешнее хранилище, когда оно не смонтировано в Marshmallow

Для работы с Marshmallow приложениям необходимо запрашивать разрешения на чтение/запись в внешние расположения. По умолчанию, ваше приложение имеет разрешение на запись в cordova.file.applicationStorageDirectory и cordova.file.externalApplicationStorageDirectory, и плагин не запрашивает разрешение для этих двух каталогов, если внешнее хранилище не смонтировано. Однако из-за ограничения, когда внешнее хранилище не смонтировано, оно будет запрашивать разрешение на запись в cordova.file.externalApplicationStorageDirectory.

Особенности iOS

  • cordova.file.applicationStorageDirectory является только для чтения; попытка сохранить файлы в корневом каталоге завершится ошибкой. Используйте одно из других cordova.file.* свойств, определенных для iOS (только applicationDirectory и applicationStorageDirectory являются только для чтения).
  • FileReader.readAsText(blob, encoding)
    • Параметр encoding не поддерживается, и кодировка UTF-8 всегда активна.

Расположение постоянного хранилища iOS

Существует два допустимых расположения для сохранения постоянных файлов на устройстве iOS: каталог Documents и каталог Library. Предыдущие версии плагина всегда сохраняли постоянные файлы только в каталоге Documents. Это имело побочный эффект, делая все файлы приложения видимыми в iTunes, что часто нежелательно, особенно для приложений, которые обрабатывают множество небольших файлов, а не создают полные документы для экспорта, что является предполагаемым назначением каталога.

Теперь можно выбрать, сохранять ли файлы в каталоге Documents или Library, с предпочтением в файле config.xml вашего приложения. Для этого добавьте одну из этих двух строк в config.xml:

<preference name="iosPersistentFileLocation" value="Library" />

<preference name="iosPersistentFileLocation" value="Compatibility" />

Без этой строки плагин File будет использовать Compatibility в качестве значения по умолчанию. Если тег предпочтения присутствует, и не является одним из этих значений, приложение не запустится.

Если ваше приложение уже было выпущено пользователям, используя более старую (до 1.0) версию этого плагина и сохранило файлы в постоянной файловой системе, то вы должны установить предпочтение на Compatibility. Переключение места хранения на Library означало бы, что существующие пользователи, обновляющие своё приложение, не смогут получить доступ к ранее сохранённым файлам.

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

Особенности браузеров

Общие особенности и замечания

  • Каждый браузер использует свою собственную защищённую файловую систему. IE и Firefox используют IndexedDB в качестве основы. Все браузеры используют прямой слеш в качестве разделителя каталогов в пути.
  • Элементы каталога должны создаваться последовательно. Например, вызов fs.root.getDirectory('dir1/dir2', {create:true}, successCallback, errorCallback) завершится ошибкой, если каталог dir1 не существует.
  • Плагин запрашивает разрешение пользователя на использование постоянного хранилища при первом запуске приложения.
  • Плагин поддерживает cdvfile://localhost (локальные ресурсы) только. Т.е. внешние ресурсы не поддерживаются через cdvfile.
  • Плагин не следует "Ограничения на имена в API файловой системы 8.3".
  • Функции «Blob и File» close не поддерживаются.
  • FileSaver и BlobBuilder не поддерживаются этим плагином и не имеют заглушек.
  • Плагин не поддерживает requestAllFileSystems. Эта функция также отсутствует в спецификациях.
  • Элементы каталога не будут удалены, если вы используете флаг create: true для существующего каталога.
  • Файлы, созданные с помощью конструктора, не поддерживаются. Вместо этого следует использовать метод entry.file.
  • Каждый браузер использует свою форму ссылок на URL-адреса blob.
  • Функция readAsDataURL поддерживается, но тип медиа в Chrome зависит от расширения имени файла, тип медиа в IE всегда пустой (что соответствует text-plain согласно спецификации), тип медиа в Firefox всегда application/octet-stream. Например, если содержимое abcdefg, то Firefox возвращает data:application/octet-stream;base64,YWJjZGVmZw==, IE возвращает data:;base64,YWJjZGVmZw==, Chrome возвращает data:<mediatype depending on extension of entry name>;base64,YWJjZGVmZw==.
  • Функция toInternalURL возвращает путь в формате file:///persistent/path/to/entry (Firefox, IE). Chrome возвращает путь в формате cdvfile://localhost/persistent/file.

Особенности Chrome

  • Файловая система Chrome не готова сразу после события готовности устройства. В качестве обходного решения можно подписаться на событие filePluginIsReady. Пример: javascript window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false); Можно использовать функцию window.isFilePluginReadyRaised для проверки, уже ли событие было возбуждено.
  • Квоты файловой системы Chrome TEMPORARY и PERSISTENT в window.requestFileSystem не ограничены.
  • Для увеличения квоты постоянного хранилища в Chrome нужно вызвать метод window.initPersistentFileSystem. Квота постоянного хранилища по умолчанию составляет 5 МБ.
  • Chrome требует аргумент --allow-file-access-from-files run для поддержки API через протокол file:///.
  • Объект File не будет изменён, если вы используете флаг {create:true} при получении существующего Entry.
  • Свойство events cancelable установлено в true в Chrome. Это противоречит спецификации.
  • Функция toURL в Chrome возвращает путь, начинающийся с filesystem:, в зависимости от хоста приложения. Например, filesystem:file:///persistent/somefile.txt, filesystem:http://localhost:8080/persistent/somefile.txt.
  • Результат функции toURL не содержит заключительного слэша в случае записи в каталог. Chrome правильно обрабатывает каталоги с URL-адресами, оканчивающимися на слэш.
  • Метод resolveLocalFileSystemURL требует, чтобы входящий url имел префикс filesystem. Например, параметр url для resolveLocalFileSystemURL должен иметь вид filesystem:file:///persistent/somefile.txt в отличие от вида file:///persistent/somefile.txt в Android.
  • Устаревшая функция toNativeURL не поддерживается и не имеет заглушки.
  • Функция setMetadata не указана в спецификациях и не поддерживается.
  • INVALIDMODIFICATIONERR (код: 9) выбрасывается вместо SYNTAX_ERR(код: 8) при запросе несуществующей файловой системы.
  • INVALIDMODIFICATIONERR (код: 9) выбрасывается вместо PATHEXISTSERR(код: 12) при попытке эксклюзивного создания файла или каталога, который уже существует.
  • INVALIDMODIFICATIONERR (код: 9) выбрасывается вместо NOMODIFICATIONALLOWED_ERR(код: 6) при попытке вызвать removeRecursively на корневой файловой системе.
  • INVALIDMODIFICATIONERR (код: 9) выбрасывается вместо NOTFOUNDERR(код: 1) при попытке переместить в каталог, которого нет.

Особенности реализации на базе IndexedDB (Firefox и IE)

  • . и .. не поддерживаются.
  • IE не поддерживает режим file:///; поддерживается только режим размещения (http://localhost:xxxx).
  • Размер файловой системы Firefox не ограничен, но каждое расширение размером 50 МБ будет запрашивать разрешение пользователя. IE10 позволяет до 10 МБ объединённых AppCache и IndexedDB, используемых в реализации файловой системы, без запроса, после достижения этого уровня вас попросят разрешить увеличение до максимума 250 МБ на сайт. Поэтому параметр size для функции requestFileSystem не влияет на файловую систему в Firefox и IE.
  • Функция readAsBinaryString не указана в спецификации и не поддерживается в IE и не имеет заглушки.
  • file.type всегда равно null.
  • Не следует создавать запись, используя результат вызова обратного вызова DirectoryEntry, который был удалён. В противном случае вы получите «зависающую запись».
  • Перед чтением файла, который только что был записан, необходимо получить новый экземпляр этого файла.
  • Функция setMetadata, которая не указана в спецификации, поддерживает только изменение поля modificationTime.
  • Функции copyTo и moveTo не поддерживают каталоги.
  • Метаданные каталогов не поддерживаются.
  • И Entry.remove, и directoryEntry.removeRecursively не завершаются ошибкой при удалении непустых каталогов — удаляемые каталоги очищаются вместе с содержимым.
  • Функции abort и truncate не поддерживаются.
  • События progress не генерируются. Например, этот обработчик не будет выполнен: javascript writer.onprogress = function() { /*commands*/ };

Примечания по обновлению

В версии 1.0.0 этого плагина структуры FileEntry и DirectoryEntry были изменены, чтобы соответствовать опубликованной спецификации.

Предыдущие версии (до 1.0.0) плагина сохраняли абсолютный путь к файлу устройства в свойстве fullPath объектов Entry. Эти пути обычно выглядели как

/var/mobile/Applications/<application UUID>/Documents/path/to/file  (iOS)
/storage/emulated/0/path/to/file                                    (Android)

Эти пути также возвращались методом toURL() объектов Entry.

С версии 1.0.0 свойство fullPath представляет путь к файлу, относительно корня файловой системы HTML. Таким образом, вышеупомянутые пути теперь оба будут представлены объектом FileEntry со свойством fullPath

/path/to/file

Если ваше приложение работает с абсолютными путями устройства, и вы ранее получали эти пути через свойство fullPath объектов Entry, то вы должны обновить свой код, чтобы использовать entry.toURL() вместо него.

Для обеспечения обратной совместимости метод resolveLocalFileSystemURL() будет принимать абсолютный путь устройства и возвращать объект Entry соответствующий ему, если этот файл существует в файловых системах TEMPORARY или PERSISTENT.

Это особенно было проблемой для плагина File-Transfer, который ранее использовал абсолютные пути устройства (и по-прежнему может их принимать). Он был обновлён для корректной работы с URL-адресами FileSystem, поэтому замена entry.fullPath на entry.toURL() должна решить любые проблемы с работой этого плагина с файлами на устройстве.

В версии 1.1.0 значение возвращаемое toURL() было изменено (см. CB-6394) для возвращения абсолютного URL-адреса 'file://' где это возможно. Для обеспечения URL-адреса 'cdvfile:' вы можете использовать toInternalURL() теперь. Этот метод теперь возвращает URL-адреса файловой системы вида

cdvfile://localhost/persistent/path/to/file

которые можно использовать для уникальной идентификации файла.

Протокол cdvfile

Назначение

cdvfile://localhost/persistent|temporary|another-fs-root*/path/to/file можно использовать для платформенно-независимых путей к файлам. Пути cdvfile поддерживаются базовыми плагинами — например, вы можете загрузить файл mp3 в cdvfile-путь через cordova-plugin-file-transfer и воспроизвести его через cordova-plugin-media.

*Примечание: Подробнее см. Где сохранять файлы, Структуры файловых систем и Настройка плагина для получения дополнительной информации о доступных корнях файловой системы.

Для использования cdvfile в качестве тега src можно преобразовать его в локальный путь с помощью метода toURL() разрешенного объекта fileEntry, который можно получить с помощью resolveLocalFileSystemURL — см. примеры ниже.

Также можно напрямую использовать cdvfile:// пути в DOM, например:

<img src="cdvfile://localhost/persistent/img/logo.png" />

Примечание: Этот метод требует обновлений правил Content Security:

  • Добавьте схему cdvfile: в тег мета-данных Content-Security-Policy страницы index, например:
    • <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap:cdvfile:https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
  • Добавьте <access origin="cdvfile://*" /> в config.xml.

Преобразование cdvfile:// в локальный путь

resolveLocalFileSystemURL('cdvfile://localhost/temporary/path/to/file.mp4', function(entry) {
    var nativePath = entry.toURL();
    console.log('Native URI: ' + nativePath);
    document.getElementById('video').src = nativePath;

Преобразование локального пути в cdvfile://

resolveLocalFileSystemURL(nativePath, function(entry) {
    console.log('cdvfile URI: ' + entry.toInternalURL());

Использование cdvfile в плагинах ядра

fileTransfer.download(uri, 'cdvfile://localhost/temporary/path/to/file.mp3', function (entry) { ...
var my_media = new Media('cdvfile://localhost/temporary/path/to/file.mp3', ...);
my_media.play();

Особенности cdvfile

  • Использование cdvfile:// путей в DOM не поддерживается на платформе Windows (путь можно преобразовать в локальный).

Список кодов ошибок и их значений

При возникновении ошибки будет использован один из следующих кодов.

Код Константа
1 NOT_FOUND_ERR
2 SECURITY_ERR
3 ABORT_ERR
4 NOT_READABLE_ERR
5 ENCODING_ERR
6 NO_MODIFICATION_ALLOWED_ERR
7 INVALID_STATE_ERR
8 SYNTAX_ERR
9 INVALID_MODIFICATION_ERR
10 QUOTA_EXCEEDED_ERR
11 TYPE_MISMATCH_ERR
12 PATH_EXISTS_ERR

Настройка плагина (необязательно)

Набор доступных файловых систем можно настраивать для каждой платформы. iOS и Android распознают тег в config.xml, который указывает имена файловых систем для установки. По умолчанию все корневые файловые системы включены.

<preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" />
<preference name="AndroidExtraFilesystems" value="files,files-external,documents,sdcard,cache,cache-external,assets,root" />

Android

  • files: Каталог внутренней файловой системы приложения
  • files-external: Каталог внешней файловой системы приложения
  • sdcard: Глобальный каталог внешней файловой системы (это корень SD-карты, если она установлена). Для использования этого каталога требуется разрешение android.permission.WRITE_EXTERNAL_STORAGE.
  • cache: Каталог кэша приложения
  • cache-external: Каталог внешнего кэша приложения
  • assets: Сборка приложения (только чтение)
  • root: Вся файловая система устройства

Android также поддерживает специальную файловую систему под названием "documents", которая представляет собой подкаталог "/Documents/" в файловой системе "files".

iOS

  • library: Каталог Library приложения
  • documents: Каталог Documents приложения
  • cache: Каталог Cache приложения
  • bundle: Сборка приложения; расположение приложения на диске (только чтение)
  • root: Вся файловая система устройства

По умолчанию каталоги Library и Documents могут синхронизироваться с iCloud. Также можно запросить две дополнительные файловые системы, library-nosync и documents-nosync, которые представляют собой специальные несинхронизируемые каталоги внутри файловых систем /Library или /Documents.

Пример: Создание файлов и каталогов, запись, чтение и добавление файлов

Плагин File позволяет выполнять такие действия, как хранение файлов в временном или постоянном хранилище приложения (хранилище в пределах приложения) и в других, зависящих от платформы, местах. Приведенные ниже фрагменты кода демонстрируют различные задачи, включая:

  • Доступ к файловой системе
  • Использование кроссплатформенных Cordova URL файлов для хранения файлов (см. Где хранить файлы для получения дополнительной информации)
  • Создание файлов и каталогов
  • Запись в файлы
  • Чтение файлов
  • Добавление в файлы
  • Отображение файла изображения

Создание постоянного файла

Прежде чем использовать API плагина File, вы можете получить доступ к файловой системе, используя requestFileSystem. При этом можно запросить постоянное или временное хранилище. Постоянное хранилище не удаляется, пока пользователь не даст разрешение на удаление.

При получении доступа к файловой системе с помощью requestFileSystem, доступ предоставляется только для хранилища приложения (хранилище ограничивает доступ приложением), а не для общего доступа к любому каталогу файловой системы устройства. (Для доступа к каталогам файловой системы за пределами хранилища приложения используйте другие методы, такие как window.resolveLocalFileSystemURL, которые поддерживают платформозависимые расположения. Пример см. в разделе Добавление файла.)

Вот запрос на постоянное хранилище.

Примечание При работе с клиентами WebView (вместо браузера) или с нативными приложениями (Windows), вам не нужно использовать requestQuota перед использованием постоянного хранилища.

window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) {

    console.log('file system open: ' + fs.name);
    fs.root.getFile("newPersistentFile.txt", { create: true, exclusive: false }, function (fileEntry) {

        console.log("fileEntry is file?" + fileEntry.isFile.toString());
        // fileEntry.name == 'someFile.txt'
        // fileEntry.fullPath == '/someFile.txt'
        writeFile(fileEntry, null);

    }, onErrorCreateFile);

}, onErrorLoadFs);

Обратный вызов success получает объект FileSystem (fs). Используйте fs.root для возврата объекта DirectoryEntry, который можно использовать для создания или получения файла (вызвав getFile). В этом примере fs.root — это объект DirectoryEntry, который представляет постоянное хранилище в хранилище приложения.

Обратный вызов success для getFile получает объект FileEntry. Его можно использовать для выполнения операций записи и чтения файла.

Создание временного файла

Вот пример запроса на временное хранилище. Временное хранилище может быть удалено операционной системой, если на устройстве не хватает памяти.

window.requestFileSystem(window.TEMPORARY, 5 * 1024 * 1024, function (fs) {

    console.log('file system open: ' + fs.name);
    createFile(fs.root, "newTempFile.txt", false);

}, onErrorLoadFs);

При использовании временного хранилища можно создать или получить файл, вызвав getFile. Как и в примере с постоянным хранилищем, это даст вам объект FileEntry, который можно использовать для операций чтения или записи.

function createFile(dirEntry, fileName, isAppend) {
    // Creates a new file or returns the file if it already exists.
    dirEntry.getFile(fileName, {create: true, exclusive: false}, function(fileEntry) {

        writeFile(fileEntry, null, isAppend);

    }, onErrorCreateFile);

}

Запись в файл

После получения объекта FileEntry можно записать в файл, вызвав createWriter, который возвращает объект FileWriter в обратном вызове success. Вызовите метод write объекта FileWriter для записи в файл.

function writeFile(fileEntry, dataObj) {
    // Create a FileWriter object for our FileEntry (log.txt).
    fileEntry.createWriter(function (fileWriter) {

        fileWriter.onwriteend = function() {
            console.log("Successful file write...");
            readFile(fileEntry);
        };

        fileWriter.onerror = function (e) {
            console.log("Failed file write: " + e.toString());
        };

        // If data object is not passed in,
        // create a new Blob instead.
        if (!dataObj) {
            dataObj = new Blob(['some file data'], { type: 'text/plain' });
        }

        fileWriter.write(dataObj);
    });
}

Чтение файла

Для чтения существующего файла также необходим объект FileEntry. Используйте свойство file объекта FileEntry для получения ссылки на файл, а затем создайте новый объект FileReader. Можно использовать методы, такие как readAsText для запуска операции чтения. Когда операция чтения завершена, this.result сохраняет результат операции чтения.

function readFile(fileEntry) {

    fileEntry.file(function (file) {
        var reader = new FileReader();

        reader.onloadend = function() {
            console.log("Successful file read: " + this.result);
            displayFileData(fileEntry.fullPath + ": " + this.result);
        };

        reader.readAsText(file);

    }, onErrorReadFile);
}

Добавление в файл с использованием альтернативных методов

Конечно, часто вам нужно будет добавлять данные в существующие файлы, а не создавать новые. Вот пример этого. Этот пример демонстрирует другой способ доступа к файловой системе с помощью window.resolveLocalFileSystemURL. В этом примере передайте кроссплатформенный URL файла Cordova, cordova.file.dataDirectory, в функцию. Обратный вызов success получает объект DirectoryEntry, который можно использовать для таких действий, как создание файла.

window.resolveLocalFileSystemURL(cordova.file.dataDirectory, function (dirEntry) {
    console.log('file system open: ' + dirEntry.name);
    var isAppend = true;
    createFile(dirEntry, "fileToAppend.txt", isAppend);
}, onErrorLoadFs);

В дополнение к этому использованию, можно использовать resolveLocalFileSystemURL для получения доступа к некоторым расположениям файловой системы, которые не являются частью хранилища приложения. См. Где хранить файлы для получения дополнительной информации; многие из этих расположений хранилищ зависят от платформы. Также можно передавать кроссплатформенные расположения файловой системы в resolveLocalFileSystemURL, используя протокол cdvfile.

Для операции добавления в функции createFile ничего нового нет (см. предыдущие примеры для получения фактического кода). createFile вызывает writeFile. В writeFile, проверяется, запрошена ли операция добавления.

После получения объекта FileWriter вызовите метод seek, передав значение индекса позиции, в которую вы хотите записать. В этом примере также проверяется, существует ли файл. После вызова seek вызовите метод write объекта FileWriter.

function writeFile(fileEntry, dataObj, isAppend) {
    // Create a FileWriter object for our FileEntry (log.txt).
    fileEntry.createWriter(function (fileWriter) {

        fileWriter.onwriteend = function() {
            console.log("Successful file read...");
            readFile(fileEntry);
        };

        fileWriter.onerror = function (e) {
            console.log("Failed file read: " + e.toString());
        };

        // If we are appending data to file, go to the end of the file.
        if (isAppend) {
            try {
                fileWriter.seek(fileWriter.length);
            }
            catch (e) {
                console.log("file doesn't exist!");
            }
        }
        fileWriter.write(dataObj);
    });
}

Хранение существующего двоичного файла

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

Прежде чем получить файл, получите ссылку на FileSystem, используя requestFileSystem. Передав window.TEMPORARY в вызов метода (как и раньше), возвращаемый объект FileSystem (fs) представляет кэш в хранилище приложения. Используйте fs.root для получения нужного объекта DirectoryEntry.

window.requestFileSystem(window.TEMPORARY, 5 * 1024 * 1024, function (fs) {

    console.log('file system open: ' + fs.name);
    getSampleFile(fs.root);

}, onErrorLoadFs);

Для полноты, вот запрос xhr для получения двоичного изображения Blob. В этом коде нет ничего специфичного для Cordova, кроме того, что вы передаете ссылку на DirectoryEntry, которую вы уже получили, в качестве аргумента функции saveFile. Вы сохраните двоичное изображение Blob и отобразите его позже после чтения файла (чтобы проверить операцию).

function getSampleFile(dirEntry) {

    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://cordova.apache.org/static/img/cordova_bot.png', true);
    xhr.responseType = 'blob';

    xhr.onload = function() {
        if (this.status == 200) {

            var blob = new Blob([this.response], { type: 'image/png' });
            saveFile(dirEntry, blob, "downloadedImage.png");
        }
    };
    xhr.send();
}

Примечание Для безопасности Cordova 5 в приведенном коде необходимо добавить доменное имя http://cordova.apache.org в элемент мета-тега Content-Security-Policy в index.html.

После получения файла скопируйте его содержимое в новый файл. Текущий объект DirectoryEntry уже связан с кэшем приложения.

function saveFile(dirEntry, fileData, fileName) {

    dirEntry.getFile(fileName, { create: true, exclusive: false }, function (fileEntry) {

        writeFile(fileEntry, fileData);

    }, onErrorCreateFile);
}

В writeFile вы передаете объект Blob в качестве dataObj, и вы сохраните его в новом файле.

function writeFile(fileEntry, dataObj, isAppend) {

    // Create a FileWriter object for our FileEntry (log.txt).
    fileEntry.createWriter(function (fileWriter) {

        fileWriter.onwriteend = function() {
            console.log("Successful file write...");
            if (dataObj.type == "image/png") {
                readBinaryFile(fileEntry);
            }
            else {
                readFile(fileEntry);
            }
        };

        fileWriter.onerror = function(e) {
            console.log("Failed file write: " + e.toString());
        };

        fileWriter.write(dataObj);
    });
}

После записи в файл прочтите его и отобразите. Вы сохранили изображение как двоичные данные, поэтому его можно прочитать с помощью FileReader.readAsArrayBuffer.

function readBinaryFile(fileEntry) {

    fileEntry.file(function (file) {
        var reader = new FileReader();

        reader.onloadend = function() {

            console.log("Successful file write: " + this.result);
            displayFileData(fileEntry.fullPath + ": " + this.result);

            var blob = new Blob([new Uint8Array(this.result)], { type: "image/png" });
            displayImage(blob);
        };

        reader.readAsArrayBuffer(file);

    }, onErrorReadFile);
}

После прочтения данных вы можете отобразить изображение с помощью такого кода. Используйте window.URL.createObjectURL для получения строкового представления DOM для изображения Blob.

function displayImage(blob) {

    // Displays image if result is a valid DOM string for an image.
    var elem = document.getElementById('imageFile');
    // Note: Use window.URL.revokeObjectURL when finished with image.
    elem.src = window.URL.createObjectURL(blob);
}

Отображение файла изображения

Для отображения изображения с помощью FileEntry можно вызвать метод toURL.

function displayImageByFileURL(fileEntry) {
    var elem = document.getElementById('imageFile');
    elem.src = fileEntry.toURL();
}

Если вы используете специфичные для платформы URI вместо FileEntry и хотите отобразить изображение, вам может потребоваться включить главную часть URI в элемент Content-Security-Policy в файле index.html. Например, в Windows 10 вы можете включить ms-appdata: в свой элемент . Вот пример.

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: ms-appdata: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">

Создание каталогов

В данном коде вы создаёте каталоги в корневом каталоге приложения. Вы можете использовать этот код с любой доступной для записи областью хранения (то есть, с любым DirectoryEntry). Здесь вы записываете в кэш приложения (предполагая, что вы использовали window.TEMPORARY для получения объекта FileSystem) передав fs.root в эту функцию.

Этот код создаёт папку /NewDirInRoot/images в кэше приложения. Для значений, специфичных для платформы, см. Схемы расположения файловой системы.

function createDirectory(rootDirEntry) {
    rootDirEntry.getDirectory('NewDirInRoot', { create: true }, function (dirEntry) {
        dirEntry.getDirectory('images', { create: true }, function (subDirEntry) {

            createFile(subDirEntry, "fileInNewSubDir.txt");

        }, onErrorGetDir);
    }, onErrorGetDir);
}

При создании подпапок необходимо создавать каждую папку отдельно, как показано в предыдущем коде.

© 2012, 2013, 2015 The Apache Software Foundation
Licensed under the Apache License 2.0.
https://cordova.apache.org/docs/en/8.x/reference/cordova-plugin-file/index.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API