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 FileSystem поддерживаются в приложениях Cordova с помощью этого плагина для платформ, перечисленных в списке Поддерживаемые платформы, за исключением платформы Browser.
Чтобы получить несколько идей о том, как использовать плагин, ознакомьтесь с примером внизу этой страницы. Для дополнительных примеров (ориентированных на браузер) см. статью HTML5 Rocks' FileSystem.
Для обзора других вариантов хранения см. руководство по хранению Cordova's хранению.
Этот плагин определяет глобальный 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- Каталог для кэшированных данных или любых файлов, которые ваше приложение может легко воссоздать. Операционная система может удалить эти файлы, когда на устройстве мало места, тем не менее, приложения не должны полагаться на ОС для удаления файлов здесь. (iOS, Android, BlackBerry 10, OSX, windows)cordova.file.externalApplicationStorageDirectory- Пространство приложения на внешнем хранилище. (Android)cordova.file.externalDataDirectory- Место для хранения файлов, специфичных для приложения, на внешнем хранилище. (Android)cordova.file.externalCacheDirectory- Кэш приложения на внешнем хранилище. (Android)cordova.file.externalRootDirectory- Корень внешнего хранилища (SD-карты). (Android, BlackBerry 10)cordova.file.tempDirectory- Временный каталог, который ОС может очистить по своему усмотрению. Не полагайтесь на ОС для очистки этого каталога; ваше приложение должно всегда удалять файлы по мере необходимости. (iOS, OSX, windows)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 | 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 | Чтение/запись? | Постоянное хранение? | Очистка ОС | Приватное? |
|---|---|---|---|---|---|---|
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.* | Чтение/запись? | Постоянное хранение? | Очистка ОС | Приватное? |
|---|---|---|---|---|---|
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. См. эту страницу для подробного обсуждения различных возможностей.
Предыдущие версии плагина выбирали местоположение временных и постоянных файлов при запуске, исходя из того, утверждало ли устройство, что карта 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: каталог «Документы» и каталог «Библиотека». Предыдущие версии плагина всегда хранили постоянные файлы только в каталоге «Документы». Это имело побочный эффект, делая все файлы приложения видимыми в iTunes, что часто нежелательно, особенно для приложений, которые обрабатывают множество небольших файлов, а не генерируют полные документы для экспорта, что является предполагаемым назначением каталога.
Теперь можно выбрать, хранить ли файлы в каталоге «Документы» или «Библиотека», задав предпочтение в файле 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 файловой системы".
- Функции 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-filesдля выполнения, чтобы поддерживать 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 правильно обрабатывает каталоги с путями, заканчивающимися слэшем. -
resolveLocalFileSystemURLметод требует, чтобы входнойurlимел префиксfilesystem. Например, параметрurlдляresolveLocalFileSystemURLдолжен быть в форматеfilesystem:file:///persistent/somefile.txt, а не в форматеfile:///persistent/somefile.txtв Android. - Устаревшая функция
toNativeURLне поддерживается и не имеет заглушки. -
setMetadataфункция не указана в спецификациях и не поддерживается. - INVALID_MODIFICATION_ERR (код: 9) выбрасывается вместо SYNTAX_ERR (код: 8) при запросе несуществующей файловой системы.
- INVALID_MODIFICATION_ERR (код: 9) выбрасывается вместо PATH_EXISTS_ERR (код: 12) при попытке исключительного создания файла или каталога, который уже существует.
- INVALID_MODIFICATION_ERR (код: 9) выбрасывается вместо NO_MODIFICATION_ALLOWED_ERR (код: 6) при попытке вызвать removeRecursively на корневой файловой системе.
- INVALID_MODIFICATION_ERR (код: 9) выбрасывается вместо NOT_FOUND_ERR (код: 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.
С версией v1.0.0 атрибут fullPath — это путь к файлу, относительно корня файловой системы HTML. Таким образом, указанные выше пути теперь оба будут представлены объектом FileEntry с атрибутом fullPath
/path/to/file
Если ваше приложение работает с абсолютными путями устройства, и вы ранее получали эти пути через свойство fullPath объектов Entry, то вам следует обновить свой код, чтобы использовать entry.toURL() вместо него.
Для обратной совместимости метод resolveLocalFileSystemURL() будет принимать абсолютный путь устройства и возвращать объект Entry, соответствующий ему, при условии, что этот файл существует в файловой системе TEMPORARY или PERSISTENT.
Эта проблема особенно актуальна для плагина File-Transfer, который ранее использовал абсолютные пути устройства (и по-прежнему может их принимать). Он был обновлён для корректной работы с URL файловой системы, поэтому замена entry.fullPath на entry.toURL() должна решить любые проблемы с работой этого плагина с файлами на устройстве.
В версии v1.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.
*Примечание: Смотрите Где хранить файлы, Макеты файловой системы и Настройка плагина для получения дополнительной информации о доступных корнях fs.
Для использования 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: Директория Библиотеки приложения -
documents: Директория Документов приложения -
cache: Директория Кэша приложения -
bundle: Пакет приложения; расположение самого приложения на диске (только для чтения) -
root: Вся файловая система устройства
По умолчанию директории Библиотека и Документы могут быть синхронизированы с 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, в элементе тега Content-Security-Policy в index.html необходимо добавить доменное имя http://cordova.apache.org.
После получения файла скопируйте содержимое в новый файл. Текущий объект 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/6.x/reference/cordova-plugin-file/index.html