cordova-plugin-file
Этот плагин реализует API файловой системы, предоставляя чтение/запись файлов на устройстве.
Этот плагин основан на нескольких спецификациях, включая: API файловой системы 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 файловой системы поддерживаются в приложениях Cordova с этим плагином для платформ, перечисленных в списке Поддерживаемые платформы, за исключением платформы браузера.
Чтобы получить несколько идей о том, как использовать плагин, ознакомьтесь с примером внизу этой страницы. Для дополнительных примеров (ориентированных на браузер) см. статью HTML5 Rocks FileSystem.
Для обзора других вариантов хранения обратитесь к руководству по хранилищу Cordova .
Этот плагин определяет глобальный cordova.file объект.
Несмотря на то, что он находится в глобальной области видимости, он недоступен до момента возникновения события deviceready.
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
console.log(cordova.file);
}
Сообщайте о проблемах в следящем за проблемами Apache Cordova.
Установка
cordova plugin add cordova-plugin-file
Поддерживаемые платформы
- Amazon Fire OS
- Android
- BlackBerry 10
- Firefox OS
- iOS
- OS X
- Windows Phone 7 и 8*
- Windows 8*
- 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.cordova.file.sharedDirectory- Файлы, доступные всем приложениям глобально (BlackBerry 10)
Структура файловой системы
Хотя технически это деталь реализации, знать, как свойства cordova.file.* отображаются на физические пути на реальном устройстве, может быть очень полезно.
Структура файловой системы iOS
| Путь устройства | cordova.file.* | iosExtraFileSystems | r/w? | постоянный? | ОС очищает? | синхр.? | приватный? |
|---|---|---|---|---|---|---|---|
/var/mobile/Applications/<UUID>/ | applicationStorageDirectory | - | r | нет | нет | нет | да |
appname.app/
| applicationDirectory | bundle | r | нет | нет | нет | да |
www/
| - | - | r | нет | нет | нет | да |
Documents/
| documentsDirectory | documents | r/w | да | нет | да | да |
NoCloud/
| - | documents-nosync | r/w | да | нет | нет | да |
Library
| - | library | r/w | да | нет | да? | да |
NoCloud/
| dataDirectory | library-nosync | r/w | да | нет | нет | да |
Cloud/
| syncedDataDirectory | - | r/w | да | нет | да | да |
Caches/
| cacheDirectory | cache | r/w | да* | да*** | нет | да |
tmp/
| tempDirectory | - | r/w | нет** | да*** | нет | да |
* Файлы сохраняются после перезапуска и обновлений приложения, но этот каталог может быть очищен по мере необходимости ОС. Ваше приложение должно иметь возможность пересоздать любые удалённые данные.
** Файлы могут сохраняться после перезапуска приложения, но не полагайтесь на это поведение. Файлы не гарантированно сохранятся после обновлений. Ваше приложение должно удалять файлы из этого каталога, когда это применимо, так как ОС не гарантирует, когда (или даже если) эти файлы будут удалены.
*** ОС может очистить содержимое этого каталога по мере необходимости, но не полагайтесь на это. Вы должны очистить этот каталог соответствующим образом для вашего приложения.
Структура файловой системы Android
| Путь к устройству | cordova.file.* | AndroidExtraFileSystems | r/w? | постоянный? | Очищается ОС | личный? |
|---|---|---|---|---|---|---|
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
| externalCacheDirectry | cache-external | r/w | Да | Нет** | Нет |
files
| externalDataDirectory | files-external | r/w | Да | Нет | Нет |
* Операционная система может периодически очищать этот каталог, но не полагайтесь на это поведение. Очищайте содержимое этого каталога как необходимо для вашего приложения. Если пользователь вручную очистит кэш, содержимое этого каталога будет удалено.
** Операционная система не очищает этот каталог автоматически; вы несете ответственность за управление содержимым самостоятельно. Если пользователь вручную очистит кэш, содержимое каталога будет удалено.
Примечание: Если внешний накопитель не может быть смонтирован, свойства cordova.file.external* null.
Макет файловой системы BlackBerry 10
| Путь к устройству | cordova.file.* | r/w? | постоянный? | Очищается ОС | личный? |
|---|---|---|---|---|---|
file:///accounts/1000/appdata/<app id>/ | applicationStorageDirectory | r | N/A | N/A | Да |
app/native
| applicationDirectory | r | N/A | N/A | Да |
data/webviews/webfs/temporary/local__0
| cacheDirectory | r/w | Нет | Да | Да |
data/webviews/webfs/persistent/local__0
| dataDirectory | r/w | Да | Нет | Да |
file:///accounts/1000/removable/sdcard | externalRemovableDirectory | r/w | Да | Нет | Нет |
file:///accounts/1000/shared | sharedDirectory | r/w | Да | Нет | Нет |
Примечание: Когда приложение развернуто в периметре работы, все пути относительны к /accounts/1000-enterprise.
Макет файловой системы OS X
| Путь к устройству | cordova.file.* | iosExtraFileSystems | r/w? | Очищается ОС | личный? |
|---|---|---|---|---|---|
/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.* | r/w? | постоянный? | Очищается ОС | личный? |
|---|---|---|---|---|---|
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. См. эту страницу для подробного обсуждения различных возможностей.
END_OF_DOCUMENT_MARKERПредыдущие версии плагина выбирали расположение временных и постоянных файлов при запуске, основываясь на том, смонтирована ли карта 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 обычно рекомендуется.
Особенности Firefox OS
API файловой системы не поддерживается Firefox OS напрямую и реализована как обёртка поверх indexedDB.
- Не завершается ошибкой при удалении непустых каталогов
- Не поддерживает метаданные для каталогов
- Методы
copyToиmoveToне поддерживают каталоги
Поддерживаются следующие пути к данным:
-
applicationDirectory- Используетxhrдля получения локальных файлов, упакованных с приложением. -
dataDirectory- Для постоянных файлов данных, специфичных для приложения. -
cacheDirectory- Кэшированные файлы, которые должны сохраняться после перезапуска приложения (приложения не должны полагаться на ОС для удаления файлов из этой папки).
Особенности браузеров
Общие особенности и замечания
- Каждый браузер использует свою собственную изолированную файловую систему. 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 вместо этого.
- Каждый браузер использует свою форму для ссылок на blob URL.
-
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 не сразу готова после события device ready. В качестве обходного пути вы можете подписаться на событие
filePluginIsReady. Пример:javascript window.addEventListener('filePluginIsReady', function(){ console.log('File plugin is ready');}, false);Вы можете использовать функциюwindow.isFilePluginReadyRaisedдля проверки того, было ли событие уже вызвано. - Квоты файловой системы TEMPORARY и PERSISTENT в window.requestFileSystem в Chrome не ограничены.
- Чтобы увеличить объём постоянного хранилища в Chrome, нужно вызвать метод
window.initPersistentFileSystem. Объём постоянного хранилища по умолчанию составляет 5 МБ. - Chrome требует аргумента
--allow-file-access-from-filesrun для поддержки 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функции не поддерживаются. - События прогресса не генерируются. Например, этот обработчик не будет выполнен:
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.
Это особенно актуально для плагина передачи файлов, который ранее использовал абсолютные пути на устройстве (и может их по-прежнему принимать). Он был обновлён, чтобы правильно работать с URL-адресами файловой системы, поэтому замена 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" />
Примечание: Этот метод требует следующих обновлений правил безопасности контента:
- Добавьте схему
cdvfile:в тег метаContent-Security-Policyстраницы индекса, например:-
<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 позволяет выполнять такие действия, как хранение файлов во временном или постоянном хранилище приложения (хранилище приложения) и хранение файлов в других зависящих от платформы расположениях. Примеры кода в этом разделе демонстрируют различные задачи, включая:
- Доступ к файловой системе
- Использование кроссплатформенных URL-адресов Cordova для хранения файлов (см. Где хранить файлы для получения дополнительной информации)
- Создание файлов и каталогов
- Запись в файлы
- Чтение файлов
- Добавление файлов
- Отображение файла изображения
Создание постоянного файла
Прежде чем использовать API плагина File, вы можете получить доступ к файловой системе с помощью requestFileSystem. При этом можно запросить постоянное или временное хранилище. Постоянное хранилище не будет удалено, пока пользователь не разрешит это.
При получении доступа к файловой системе с помощью requestFileSystem, доступ предоставляется только для файловой системы приложения (ограничения приложения), а не для общего доступа к любому расположению файловой системы на устройстве. (Чтобы получить доступ к расположениям файловой системы за пределами хранилища приложения, используйте другие методы, такие как window.requestLocalFileSystemURL, которые поддерживают платформозависимые расположения. Пример см. в разделе Добавление файла.)
Вот запрос на постоянное хранилище.
Примечание При работе с клиентами 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);
Обратный вызов успеха получает объект FileSystem (fs). Используйте fs.root для возврата объекта DirectoryEntry, который можно использовать для создания или получения файла (вызовом getFile). В данном примере fs.root — это объект DirectoryEntry, представляющий постоянное хранилище в файловой системе приложения.
Обратный вызов успеха для 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 в обработчике успеха. Вызовите метод 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, в функцию. Обработчик успеха получает объект 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/7.x/reference/cordova-plugin-file/index.html