Cordova实现文件操作,本篇文章讲述的是在IOS和Android上实现以下两种需求:
1,创建文件夹和文件,从数据库获取数据并写入到文件;
2,获取指定目录文件夹下文件,并读取文件数据;
先上效果图:
创建文件夹和文件,从数据库获取数据并写入到文件
获取指定目录文件夹下文件,并读取文件数据
进入正题,下面是具体实现过程:
文件操作使用了cordova-plugin-file插件,插件地址:https://github.com/apache/cordova-plugin-file;
一,准备工作
1,安装cordova-plugin-file插件
在工程目录下执行以下命令:
sudo cordova plugin add cordova-plugin-file2,在 config.xml 文件中配置持久化文件保存位置(Persistent storage location)IOS中,默认配置或如下配置时,会保存在程序的 Documents 文件目录下
<PReference name="iosPersistentFileLocation" value="Compatibility" />要想保存到应用的 Library 文件夹下,可以如下配置<preference name="iosPersistentFileLocation" value="Library" />Android中,默认配置或如下配置时,会保存在 /data/data/<packageId> 下面<preference name="AndroidPersistentFileLocation" value="Internal" />要想保存到SD卡或等效的存储分区,可以如下配置:<preference name="AndroidPersistentFileLocation" value="Compatibility" />我是如下配置的:
<preference name="iosPersistentFileLocation" value="Compatibility" /><preference name="AndroidPersistentFileLocation" value="Compatibility" />3,在 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" />至于各种value的区别,这里就懒得写了,直接贴上官方原话:
Android
files
: The application's internal file storage directoryfiles-external
: The application's external file storage directorysdcard
: The global external file storage directory (this is the root of the SD card, if one is installed). You must have theandroid.permission.WRITE_EXTERNAL_STORAGE
permission to use this.cache
: The application's internal cache directorycache-external
: The application's external cache directoryassets
: The application's bundle (read-only)root
: The entire device filesystemAndroid also supports a special filesystem named "documents", which represents a "/Documents/" subdirectory within the "files" filesystem.
iOS
library
: The application's Library directorydocuments
: The application's Documents directorycache
: The application's Cache directorybundle
: The application's bundle; the location of the app itself on disk (read-only)root
: The entire device filesystemBy default, the library and documents directories can be synced to iCloud. You can also request two additional filesystems,
library-nosync
anddocuments-nosync
, which represent a special non-synced directory within the/Library
or/Documents
filesystem.我是如下配置的:
<preference name="iosExtraFilesystems" value="library,library-nosync,documents,documents-nosync,cache,bundle,root" /><preference name="AndroidExtraFilesystems" value="sdcard" />4,Android平台需要配置文件权限
在AndroidManifest.xml中如下配置:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />二,具体实现要下班了,就不详细讲解了,直接贴代码://文本内容var tasksStr = '';/** 从数据库查询数据,写入到指定目录下文件中* */function exportDataFromDb() { selectDataFromConcernsDeviceInfos('admin', function (result) { if (result.length != 0) { for (var i = 0; i < result.length; i++) { tasksStr = tasksStr + JSON.stringify(result[i]); } console.log(tasksStr); createAndWriteFile(); } else { console.log('no data'); } });}/* * 打开或创建文件夹,创建文件并写入内容 * Android:sdcard/xbrother/assets目录 * IOS:cdvfile://localhost/persistent/xbrother/assets目录 * 文件目录存在则打开,不存在则创建 * */function createAndWriteFile() { window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) { console.log('打开的文件系统: ' + fs.name); fs.root.getDirectory('xbrother', {create: true}, function (dirEntry) { dirEntry.getDirectory('assets', {create: true}, function (subDirEntry) { subDirEntry.getFile("task.json", {create: true, exclusive: false}, function (fileEntry) { fileEntry.name == 'task.json'; fileEntry.fullPath == 'xbrother/assets/task.json'; //文件内容 var dataObj = new Blob([tasksStr], {type: 'text/plain'}); //写入文件 writeFile(fileEntry, dataObj); }, onErrorCreateFile); }, onErrorGetDir); }, onErrorGetDir); }, onErrorLoadFs);}/** 依次打开指定目录文件夹,读取文件内容 * Android:sdcard/xbrother/assets/task.json * IOS:cdvfile://localhost/persistent/xbrother/assets/task.json* 目录和文件存在则打开,不存在则退出* */function getAndReadFile() { window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fs) { console.log('打开的文件系统: ' + fs.name); fs.root.getDirectory('xbrother', {create: false}, function (dirEntry) { dirEntry.getDirectory('assets', {create: false}, function (subDirEntry) { subDirEntry.getFile("task.json", {create: false, exclusive: false}, function (fileEntry) { console.log("是否是个文件?" + fileEntry.isFile.toString()); fileEntry.name == 'task.json'; fileEntry.fullPath == 'xbrother/assets/task.json'; readFile(fileEntry); }, onErrorCreateFile); }, onErrorGetDir); }, onErrorGetDir); }, onErrorLoadFs);}//将内容数据写入到文件中function writeFile(fileEntry, dataObj) { //创建一个写入对象 fileEntry.createWriter(function (fileWriter) { //文件写入成功 fileWriter.onwriteend = function () { console.log("Successful file write..."); }; //文件写入失败 fileWriter.onerror = function (e) { console.log("Failed file write: " + e.toString()); }; //写入文件 fileWriter.write(dataObj); });}//读取文件function readFile(fileEntry) { fileEntry.file(function (file) { var reader = new FileReader(); reader.onloadend = function () { $$('#file_content_info').html(this.result); console.log("file read success:" + this.result); }; reader.readAsText(file); }, onErrorReadFile);}//FileSystem加载失败回调function onErrorLoadFs(error) { console.log("文件系统加载失败!")}//文件夹创建失败回调function onErrorGetDir(error) { console.log("文件夹创建失败!")}//文件创建失败回调function onErrorCreateFile(error) { console.log("文件创建失败!")}//读取文件失败响应function onErrorReadFile() { console.log("文件读取失败!");}三,注意问题关于ios文件拷出问题
1,如果想要将ios中创建的文件拷贝出来,需要在.plist作如下配置:
<key>UIFileSharingEnabled</key>当然也可以直接在Xcode中配置:2,不建议用iTunes拷贝。以我血的教训为例,我明明创建了 /xbrother/assets目录,并在目录下创建了task.json文件,然而用iTunes查看时,却只能看到xbrother文件夹,下一层级的assets文件夹和文件夹下task.json文件根本就看!不!到!多次插拔手机还是无解,一直以为是我代码写的有问题。反复检查代码确认没问题后,换一款软件(同步助手)来查看,居然都能看见了!如上面效果图中所示。白白在这个问题上郁闷一个多小时。当然直到现在还是没搞懂,哪位仁兄知道原因的话请务必不吝赐教。
3,在.plist中配置了iTunes文件共享权限后,在上架到AppStore时,需要备注说明开启此权限的原因。我提交后没能通过苹果审核,此部分苹果反馈如下:
Information Needed
We began the review of your app but aren't able to continue because we need additional information about your app.At your earliest opportunity, please review the following question(s) and provide as much detailed information as you can. The more information you can provide upfront, the sooner we can complete your review.- What is the purpose of enabling iTunes File Sharing? Please explain the need for this, and where the usage can be found in your binary.Once you reply to this message in Resolution Center with the requested information, we can proceed with your review.
其实这个插件功能挺强大,本篇文章只讲了自己在项目中用到的部分,想要全面了解这个插件的功能,建议直接github看项目文档,地址是:https://github.com/apache/cordova-plugin-file/blob/master/README.md。
下面这篇文章也写的特别好:
Cordova - file插件的使用详解(文件的创建、读写,文件夹创建等)
关于文件上传下载部分,可以结合插件cordova-plugin-file-transfer实现,关于这部分,下面这篇文章讲的特别好:
Cordova - fileTransfer插件的使用详解(实现文件上传、下载)
以上写的有不对的地方欢迎各位朋友批评指正。
新闻热点
疑难解答