文件系统插件

这个插件实现了文件的读写、访问文件。提供了一个全局对象cordova.file,但需要deviceready事件之后才能使用。

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

在哪里存储文件

 每一个URl file:///path/to/spot/, 使用window.resolveLocalFileSystemURL()可以转换为DirectoryEntry对象 

cordova.file.applicationdirectory只读目录 安装应用。(iOS,安卓)

cordova.file.applicationstoragedirectory-应用程序的 沙盒根目录;在iOS和Windows这个位置是只读的(但具体目录[喜欢文件在iOS或/地方在Windows ]是读写)。包含在 所有数据是私有的应用程序。(iOS,安卓)

cordova.file.datadirectory持续和私人数据的使用内存在 应用程序沙箱的存储(Android,如果你需要使用 外部存储器,使用externaldatadirectory。)。在iOS上,这个目录是不 同步到iCloud(使用synceddatadirectory。)。(iOS,安卓)

cordova.file.cachedirectory-缓存数据文件或文件的任何 ,您的应用程序可以重新创建容易目录。系统可能会删除这些文件在设备运行 低存储,但是,应用程序不应该依赖于操作系统删除文件在这里 。(iOS,安卓)

cordova.file.externalapplicationstoragedirectory在 外部存储的应用空间。(安卓)

cordova.file.externaldatadirectory在将应用程序特定的数据文件 外部存储。(安卓)

cordova.file.externalcachedirectory在外部存储应用程序缓存。 安卓)

cordova.file.externalrootdirectory外部存储器(SD卡)的根。(安卓)

cordova.file.tempdirectory-临时目录,操作系统可以清楚的将。不 依靠操作系统清除此目录;你的应用程序应该总是删除文件 适用。(iOS)

cordova.file.synceddatadirectory将应用程序特定的文件,应同步 (例如iCloud。(iOS)

cordova.file.documentsdirectory-私人文件的应用程序,但这是有意义的 其他应用(如Office文件)。注意:OSX这是用户的~ /文件目录(iOS,OSX)

文件系统布局

iOS文件系统布局

设备路径
cordova.file.*iosExtraFileSystemsr/w?持久化?操作系统清除
同步私有
/var/mobile/Applications/<UUID>/applicationStorageDirectory-rN/AN/AN/AYes
   appname.app/applicationDirectorybundlerN/AN/AN/AYes
      www/--rN/AN/AN/AYes
   Documents/documentsDirectorydocumentsr/wYesNoYesYes
      NoCloud/-documents-nosyncr/wYesNoNoYes
   Library-libraryr/wYesNoYes?Yes
      NoCloud/dataDirectorylibrary-nosyncr/wYesNoNoYes
      Cloud/syncedDataDirectory-r/wYesNoYesYes
      Caches/cacheDirectorycacher/wYes*Yes***NoYes
   tmp/tempDirectory-r/wNo**Yes***NoYes

*文件坚持在应用程序重新启动和升级,但这个目录可以被清除时, OS的欲望。你的程序应该能够创建任何 内容可能会被删除。

*文件可能会持续整个应用程序重新启动,但不要依赖这种行为。文件 不能保证持续在更新。你的程序应该从 这个目录时可删除文件,如操作系统不保证当(甚至 如果)这些文件被删除。

*操作系统可以清除该目录的内容时,感觉它是 是必要的,但不依赖于此。你应该清楚这个目录作为您的应用程序的适当 。

Android文件系统布局

设备路径
cordova.file.*AndroidExtraFileSystemsr/w?持久化?操作系统清除私有
file:///android_asset/applicationDirectoryassetsrN/AN/AYes
/data/data/<app-id>/applicationStorageDirectory-r/wN/AN/AYes
   cachecacheDirectorycacher/wYesYes*Yes
   filesdataDirectoryfilesr/wYesNoYes
      Documentsdocumentsr/wYesNoYes
<sdcard>/externalRootDirectorysdcardr/wYesNoNo
   Android/data/<app-id>/externalApplicationStorageDirectory-r/wYesNoNo
      cacheexternalCacheDirectorycache-externalr/wYesNo**No
      filesexternalDataDirectoryfiles-externalr/wYesNoNo

*操作系统会定期清除这个目录,但不要依赖这种行为。明确 本文内容目录为适合您的应用程序。该用户 清除缓存手动,这个目录的内容将被删除。

*操作系统并不清楚这个目录自动;你是负责管理 内容自己。如果用户清除缓存的手动, 目录中的内容将被删除
注意:如果外部存储不能安装,cordova.file.external* 属性为 null

cdvfile协议

目的
cdvfile://localhost/persistent|temporary|another-fs-root*/path/to/file可用于独立于平台的文件路径。 cdvfile路径支持的cordova核心插件

使用cdvfile作为一个标签SRC你可以把它转化为本地路径通过toURL()解决fileEntry,你可以通过resolveLocalFileSystemURL看下面的例子。
你也可以使用cdvfile:/ /直接访问DOM中的路径,例如:
<img src="cdvfile://localhost/persistent/img/logo.png" />

注意:此方法需要配置一些安全权限,例如:
*增加cdvfile: 在项目的index首页中scheme配置  Content-Security-Policy 的meta标签  e.g.:
<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 *">
*在项目的config.xml增加以下配置
<access origin="cdvfile://*" />

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());

错误代码列表和意义

当执行过程抛出一个错误,将返回一些错误代码
CodeConstant
1NOT_FOUND_ERR
2SECURITY_ERR
3ABORT_ERR
4NOT_READABLE_ERR
5ENCODING_ERR
6NO_MODIFICATION_ALLOWED_ERR
7INVALID_STATE_ERR
8SYNTAX_ERR
9INVALID_MODIFICATION_ERR
10QUOTA_EXCEEDED_ERR
11TYPE_MISMATCH_ERR
12PATH_EXISTS_ERR


示例:文件和目录,写,读创造,并追加文件

文件系统插件允许你做一个临时的为你的应用程序的存储位置或持续像存储文件的东西(沙箱存储)和存储文件的其他依赖平台的位置

创建一个持久的文件

在你使用文件的插件API,你可以使用requestFileSystem访问文件系统。当你这样做时,你可以要求持久性或临时存储。持久性存储不会除非得到用户允许删除。

当你使用requestFileSystem访问文件系统,获得批准的文件系统(Sandbox沙盒限制访问应用程序本身),不为任何设备上的文件系统位置一般访问。(访问文件系统位置在沙箱存储,使用其他方法,如window.resolveLocalFileSystemURL,支持平台的具体位置。对于这样的一个例子,看添加一个文件。)

这是一个持久性存储要求。
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);
访问成功的回调方法会返回一个文件系统的对象(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方法的输出写入文件。
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对象读取一个已存在的文件。使用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。在这个例子中,通过跨平台的 Cordova file URL,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方法后,调用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);
    });
}