uniapp Android 调用5+plus 的IO模块 操作文件管理

  • Post author:
  • Post category:uniapp


由于最近uniapp项目需要调5+puls,来操作手机文件增删改查,于是入坑了native.js>android>IO,官网文档先献上


5+puls官网文档

首先介绍一下,我们存储空间有2种模式那就是

沙盒模式

和系统公共目录

我们这里用到的是沙盒模式,app的应用根目录以内存储空间(不需要授权也能访问,默认授权了)

我们的下载文件储存到手机的地址uni.saveFile()也是储存在沙盒模式下,



沙盒模式

PRIVATE_WWW: 应用私有资源目录常量

PRIVATE_DOC: 应用私有文档目录常量


PUBLIC_DOCUMENTS

: 应用公共文档目录常量(下面例子用到的)

PUBLIC_DOWNLOADS: 应用公共下载目录常量

那么如果我想下app应用的根目录下

新建文件

或者

新建目录

怎么操作呢,

加粗样式

骚操作如下

export function createFlie(path,data) {
  return new Promise(resolve => {//这里封装了个是一个promise异步请求
    // plus.io.requestFileSystem是请求本地文件系统对象
    plus.io.requestFileSystem(
    	plus.io.PUBLIC_DOCUMENTS, // 文件系统中的根目录下的DOCUMENTS目录
    	fs => {
    		// 创建或打开文件, fs.root是根目录操作对象,直接fs表示当前操作对象
    		fs.root.getFile(path+'.json', {
    			create: true // 文件不存在则创建
    		}, fileEntry => {
    			// 文件在手机中的路径
    			// console.log(fileEntry.fullPath)
    			fileEntry.createWriter(writer => {
    				// 写入文件成功完成的回调函数
    				writer.onwrite = e => {
    					console.log("写入本地文件成功");
						resolve("写入本地文件")
    				};
    				// 写入数据
    				writer.write(JSON.stringify(data));
    			})
    		}, e => {
    			console.log("getFile failed: " + e.message);
    		});
    	},
    	e => {
    		console.log(e.message);
    	}
    );
  })
}
//查看我们新建的documents目录下的所有文件,或者删除指定文件
export function getFileList(path) {
	return new Promise(resolve => { //文件读写是一个异步请求 用promise包起来方便使用时的async+await
	//  io.dcloud.HBuilder 是真机调试的包名,,
	//"/storage/emulated/0/Android/data/io.dcloud.HBuilder/documents"
	//  如果要进行打包那么就要改成你打包包名,比如我的包名是uni.UNIACE0B00那就改成
	//  "/storage/emulated/0/Android/data/uni.UNIACE0B00/documents"
		plus.io.requestFileSystem(
			"/storage/emulated/0/Android/data/uni.UNIACE0B00/documents", //指定的目录
			function(entry) {
				var directoryReader = entry.createReader(); //获取读取目录对象
				directoryReader.readEntries(
					function(entries) {
						resolve(entries)
						//entries目录是一个数字遍历就能得到文件了,如下
						// for (var i = 0; i < entries.length; i++) {
						// 	//   entries[i].remove();  //这是删除指定的文件
						// 	console.log("文件信息:" + entries[i].name);
						// }
					},
					function(err) {
						uni.showToast({
							title: "访问目录失败:" + err.message,
							duration: 2000
						})
						console.log("访问目录失败");
					});
			},
			function(err) {
				// uni.showToast({
				// 	title: "访问指定目录失败:" + err.message,
				// 	duration: 2000
				// })
				console.log("访问指定目录失败:" + err.message);
			});
	})
}
//查看目录下的某个指定文件
export function getFileData(path) {
	return new Promise(resolve => { //文件读写是一个异步请求 用promise包起来方便使用时的async+await
		plus.io.requestFileSystem(
			plus.io.PUBLIC_DOCUMENTS,
			fs => {
				fs.root.getFile(path + '.json', {
					create: false
				}, fileEntry => {
					fileEntry.file((file) => {
						console.log("文件大小:" + file.size + '-- 文件名:' + file.name);
						//创建读取文件对象
						let fileReader = new plus.io.FileReader();
						//以文本格式读取文件数据内容
						fileReader.readAsText(file, 'utf-8');
						//文件读取操作完成时的回调函数
						fileReader.onloadend = (evt) => {
							console.log(JSON.parse(evt.target.result),
								'JSON.parse(evt.target.result)')
							resolve(JSON.parse(evt.target.result))
							// sURL = JSON.parse(evt.target.result).URL;

						}
					});
				}, e => {
					console.log("getFile failed: " + e.message);
				});
			},
			e => {
				console.log(e.message);
			}
		);
	})
}

在页面调用时

import { createFlie,getFileData,getFileList } from '@/utils/localFile'

//新建文件
async customFlie() {
let fileName=123 //fileName为你要定义的字符串文件名,
let ballList=[0]   //ballList是你要存的json数据
	let resC = await createFlie(fileName, ballList)
}

async getlist() {
     //查看某个指定的目录下的所有文件文件
	 let resFileList = await getFileList()
     //查看documents目录下的某个指定文件,比如123
     let fileName=123
     let resFileData = await getFileData(fileName)
}

上面就是操作沙盒文件的方法



系统的公共目录

那么延伸一下,如果要读取操作系统的公共目录文件方法如下

export function getFileList() {
	return new Promise(resolve => { 
    调用系统的目录文件用绝对路径在在沙盒模式的路径前+file://
		plus.io.resolveLocalFileSystemURL(
			 "file:///storage/emulated/0/DCIM/Camera",, //系统公共本地相册
			function(entry) {
				var directoryReader = entry.createReader(); //获取读取目录对象
				directoryReader.readEntries(
					function(entries) {
						resolve(entries)
						//entries目录是一个数字遍历就能得到文件了,如下
						// for (var i = 0; i < entries.length; i++) {
						// 	//   entries[i].remove();  //这是删除指定的文件
						// 	console.log("文件信息:" + entries[i].name);
						// }
					},
					function(err) {
						console.log("访问目录失败");
					});
			},
			function(err) {
				console.log("访问指定目录失败:" + err.message);
			});
	})
}

如果需要新建本地目录或者文件呢

5+plus 貌似没有提供api,需要用原生插件的方式

接下来是原生插件开发思路

android 9及以下除其他应用的内部空间不可以读写,其他任意目录的文件都可以读写。

安android 10如果 29<targetSdkVersion <30 可以在AndroidManifest.xml文件中application节点中加上android:requestLegacyExternalStorage=”true”来关闭分区,

如果大于targetSdkVersion >30,equestLegacyExternalStorage=”true”也会失效

并申请权限

<uses-permission android:name=“android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>
<uses-permission android:name=“android.permission.WRITE_EXTERNAL_STORAGE\"/>
<uses-permission android:name=“android.permission.READ_EXTERNAL_STORAGE\"/>

andorid 11+会强制执行分区存储。不允许应用读写操作非应用沙盒目录和系统公共目录下的资源文件。需要获取全部文件权限



版权声明:本文为weixin_45596949原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。