Cordova实现文件创建和读写操作(支持Android和IOS等)

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-file


2,在 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 directory
  • files-external: The application's external file storage directory
  • sdcard: The global external file storage directory (this is the root of the SD card, if one is installed). You must have the android.permission.WRITE_EXTERNAL_STORAGE permission to use this.
  • cache: The application's internal cache directory
  • cache-external: The application's external cache directory
  • assets: The application's bundle (read-only)
  • root: The entire device filesystem

Android also supports a special filesystem named "documents", which represents a "/Documents/" subdirectory within the "files" filesystem.

iOS

  • library: The application's Library directory
  • documents: The application's Documents directory
  • cache: The application's Cache directory
  • bundle: The application's bundle; the location of the app itself on disk (read-only)
  • root: The entire device filesystem

By default, the library and documents directories can be synced to iCloud. You can also request two additional filesystems, library-nosync and documents-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插件的使用详解(实现文件上传、下载)

以上只是用于技术验证的demo级别,代码写的很随意,也没有封装,勿喷。













  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值