uniapp项目 存储数据到手机本地

打开manifest.json,在App权限配置中,添加读取和写入的权限

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

方法一:

files.js代码

/* 使用该类应开启以下权限(读取和写入)<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>*/
/* 文件编码ansi(ascii):英文标准码0-127,包括控制符和其他英文字符编码,这在后来一直统一没再变过,当然它只需要一个字节保存gb2312和gbk:这两个是ancii码加上汉字的扩展,汉字多达10万,在ancii编码基础上再加一个字节表示汉字,共可表示字符65535个,包括了繁体字。因此一个中文字符包含两个字节。eclipse中默认编码方式为gbk。在Windows中文系统中ANSI是默认的编码方式。对于英文文件是ASCII编码,对于简体中文文件是GB2312编码。Unicode编码:顾名思义,这是国际统一标准编码,在这之前各国标准编码不统一,微软等公司需要为各国的计算机系统定制符合不同编码标准的系统,显然,成本太高,并且互联网的出现让不同编码标准的计算机交互变得困难,如:两国的邮件系统,会因为使用不同的编码标准而导致接受方收到的邮件是乱码。utf-8和utf-16编码:UTF的意思是(UCS Transfer Format),显然是随着互联网的出现,需要解决Unicode在网络上的传输问题。顾名思义,UTF8就是每次8个位传输数据,而UTF16就是每次16个位,只不过为了传输时的可靠性,从UNICODE到UTF时并不是直接的对应,而是要过一些算法和规则来转换。UTF-8就是在互联网上使用最广的一种unicode的实现方式。
*//*** 获取手机内置存储的根路径* 路径 -(~\内部存储\Android\data\io.dcloud.HBuilder)* @return {String}*/
const root = function(folder) {// 安卓10以下路径地址//const environment = plus.android.importClass("android.os.Environment");//return environment.getExternalStorageDirectory();//兼容安卓10+ (通用)- 路径最好为"_downloads/",否则在手机中找不到路径const localFile = plus.io.convertLocalFileSystemURL("_downloads/");return localFile;	
}/*** 获取指定文件夹下的所有文件和文件夹列表* @param {String} path 文件夹路径* @return {Array<String>} 文件和文件夹列表*/
const filelist = function(dir = '') {const File = plus.android.importClass("java.io.File");let list = [];let file = new File(dir);let tempList = file.listFiles();for (let i = 0; i < tempList.length; i++) {let fileName = tempList[i].getName();list.push(fileName);}return list;
}/*** 创建文件* @return {boolean} flase=失败(已存在、操作失败),true=成功*/
const createNewFile = function(path = '') {const File = plus.android.importClass('java.io.File');let file = new File(path);if (!file.exists()) {return file.createNewFile();}return false;
}/*** 创建文件夹* @return {boolean} flase=失败(已存在、操作失败),true=成功*/
const mkdirs = function(path = ''){const File = plus.android.importClass('java.io.File');let file = new File(path);if (!file.exists()) {return file.mkdirs();}return false;
}/*** 读取文件* @param {String} path 文件路径* @param {String} charset 编码* @return {Array<String>} 内容列表(按行读取),文件不存在或异常则返回false*/
const readTxt = function(path = '', charset = 'utf-8') {const File = plus.android.importClass('java.io.File');const InputStreamReader = plus.android.importClass('java.io.InputStreamReader');const BufferedReader = plus.android.importClass('java.io.BufferedReader');const FileInputStream = plus.android.importClass('java.io.FileInputStream');let file = new File(path);let inputStreamReader = null;let bufferedReader = null;let list = [];try {if (!file.exists()) {return false;}inputStreamReader = new InputStreamReader(new FileInputStream(file), charset);bufferedReader = new BufferedReader(inputStreamReader);let line = '';while (null != (line = bufferedReader.readLine())) {list.push(line);}bufferedReader.close();inputStreamReader.close();} catch (e) {if (null != bufferedReader) {bufferedReader.close();}if (null != inputStreamReader) {inputStreamReader.close();}return false;}return list;
}/*** 写入文件内容* @param {String} path 文件路径* @param {String} content 内容* @param {boolean} append 内容写入类型,false=不追加(覆盖原有内容),true=追加(从内容尾部写入)* @param {String} charset 编码* @return {boolean} true=成功,false=失败*/
const writeTxt = function(path = '', content = '', append = false, charset = 'utf-8') {const File = plus.android.importClass('java.io.File');const FileOutputStream = plus.android.importClass('java.io.FileOutputStream');const OutputStreamWriter = plus.android.importClass('java.io.OutputStreamWriter');var outputStreamWriter;try{// 创建文件夹和文件plus.io.requestFileSystem(plus.io.PRIVATE_DOC, fs => {fs.root.getFile(path, {create: true});});outputStreamWriter = new OutputStreamWriter(new FileOutputStream(path, append), charset);outputStreamWriter.write(content);outputStreamWriter.close();} catch (e) {if (null != outputStreamWriter) {outputStreamWriter.close();}return false;}return true; // 创建不来文件夹,不好使/* let file = new File(path);try {//不存在则创建新的文件if (!file.exists()) {// 创建文件夹file.mkdirs();if(file.exists){// file.createNewFile() 创建文件夹创建不了let fileName = new File("demo.json");fileName.createNewFile();}}outputStreamWriter = new OutputStreamWriter(new FileOutputStream(path, append), charset);outputStreamWriter.write(content);outputStreamWriter.close();} catch (e) {if (null != outputStreamWriter) {outputStreamWriter.close();}return false;}return true; */
}/*** 判断文件是否存在* @param path 文件路径* @return true=存在 false=不存在*/
const isFileExist = function(path = ''){const File = plus.android.importClass('java.io.File');return new File(path).exists()
}/*** 删除文件* @param {String} path*/
const deleteFile = function(path = ''){const File = plus.android.importClass('java.io.File');let file = new File(path);if (file.exists()) {return file.delete();}return false  
} export default {root,filelist,createNewFile,mkdirs,readTxt,writeTxt,isFileExist,deleteFile
}

使用方法:

import FileJS  from '@/utils/files.js';//引用方法
           // 获取文件路径const filePaths = FileJS.root()+'/demo/dd.json';// 获取要写入的内容const content = data;// 写入文件const result =  FileJS.writeTxt(filePaths, content);// 如果写入成功if (result) {console.log("文件写入成功",filePaths);} else {console.error("文件写入失败");}// 读取文件内容const readData = FileJS.readTxt(filePaths)console.log("readData"readData);

 方法二:

应用私有资源目录,对应常量plus.io.PRIVATE_WWW,仅应用自身可读应用私有文档目录,对应常量plus.io.PRIVATE_DOC,仅应用自身可读写应用公共文档目录,对应常量plus.io.PUBLIC_DOCUMENTS,多应用时都可读写,常用于保存应用间共享文件应用公共下载目录,对应常量plus.io.PUBLIC_DOWNLOADS,多应用时都可读写,常用于保存下载文件常量:PRIVATE_WWW: 应用私有资源目录常量PRIVATE_DOC: 应用私有文档目录常量PUBLIC_DOCUMENTS: 应用公共文档目录常量PUBLIC_DOWNLOADS: 应用公共下载目录常量方法:requestFileSystem: 请求本地文件系统对象resolveLocalFileSystemURL: 通过URL参数获取目录对象或文件convertLocalFileSystemURL: 将本地URL路径转换成平台绝对路径convertAbsoluteFileSystem: 将平台绝对路径转换成本地URL路getAudioInfo: 获取音频文件信息getFileInfo: 获取文件信息getImageInfo: 获取图片信息getVideoInfo: 获取视频文件信息

toolFile.js:

// 读取json文件
function getJsonData(path) { //path:路径console.log("getData");return new Promise(resolve => { //文件读写是一个异步请求 用promise包起来方便使用时的async+awaitplus.io.requestFileSystem(plus.io.PUBLIC_DOCUMENTS, fs => { //请求文件系统fs.root.getFile(path, { //请求地址文件  '/storage/emulated/0/config.txt'为根目录  '/config.txt'为/storage/Android/data/io.dcloud.HBuilder(包名)/documents/config.jscreate: true //当文件不存在时创建}, fileEntry => {fileEntry.file(function(file) {let fileReader = new plus.io.FileReader(); //new一个可以用来读取文件的对象fileReaderfileReader.readAsText(file, "utf-8"); //读文件的格式fileReader.onerror = e => { //读文件失败console.log("获取文件失败", fileReader.error);plus.nativeUI.toast("获取文件失败,请重启应用", {background: "rgba(255, 255, 255, 0.6)",});return;};fileReader.onload = e => { //读文件成功console.log("读取文件成功");let txtData = e.target.result;// console.log(txtData);resolve(txtData); //回调函数内的值想返回到函数外部  就用promise+resolve来返回出去};});}, error => {console.log("2新建获取文件失败", error);plus.nativeUI.toast("获取文件失败,请重启应用", {background: "rgba(255, 255, 255, 0.6)",});return;});},e => {console.log("1请求文件系统失败", e.message);plus.nativeUI.toast("请求系统失败,请重启应用", {background:  "rgba(255, 255, 255, 0.6)",});return;});});
};
// 写入josn文件
function changeData(path, seek, writeData) { //参数1:上传路径,参数2:seek方法可设置文件操作指定位置,参数3:写入的json数据return new Promise(resolve => {// resolveLocalFileSystemURL  requestFileSystem  PUBLIC_DOCUMENTS PRIVATE_DOCplus.io.requestFileSystem(plus.io.PRIVATE_DOC, fs => {fs.root.getFile(path, {create: true}, fileEntry => {fileEntry.file(file => {fileEntry.createWriter(writer => {console.log(fs.root.toURL(),'写入路径')plus.nativeUI.showWaiting("正在保存信息");writer.seek(seek); //覆盖文件// 对象转成json字符串/* const writeDataTemp = JSON.stringify(writeData, null,"\r").replace(/[\r]/g, ""); */writer.write(writeData); // 整个文件重写writer.onerror = function() {console.log("写入文件失败", writer.error.message);plus.nativeUI.closeWaiting();plus.nativeUI.toast("修改信息失败,请重新操作", {background: "rgba(255, 255, 255, 0.6)",});return;};writer.onsuccess = function() { //填写文件成功plus.nativeUI.closeWaiting();plus.nativeUI.toast("保存成功", {// background: "rgba(255, 255, 255, 0.6)",});resolve("1");};},error => {console.log("3创建creactWriter失败", error);plus.nativeUI.toast("保存文件失败,请重新操作", {// background: "#ffa38c",});return;});});},error => {console.log("2获取文件失败", error);plus.nativeUI.toast("保存文件失败,请重新操作", {// background: "#ffa38c",});return;});}, e => {console.log("1请求文件系统失败", e.message);plus.nativeUI.toast("请求系统失败,请重新操作", {// background: "#ffa38c",});return;});});
}
/*** 储存文件到指定的地址:把一个文件移动到另外一个位置 剪切文件 重命名文件* @param {String} url				 	新的地址 _doc/ 开头* @param {String} file                	原文件地址* @param {String} newfilename 			新的文件名*/
async function saveFile(url, file, newfilename) {let c = await creatDirs(url)let isokm = moveDirectyOrFile(file, url + "/", newfilename);return isokm
}
//循环创建目录 url:"_doc/...."  _doc开头
async function creatDirs(url) {let urllist = url.split("/");console.log(urllist)//创建文件夹let u = "";for (let i = 0; i < urllist.length - 1; i++) {let j = i;if (i == 0) {u = urllist[i];} else {u = u + "/" + urllist[i];}console.log(i + "-------------------")console.log(u)console.log(urllist[j + 1])await CreateNewDir(u, urllist[j + 1]);}
}
//重命名目录或文件名
function moveDirectyOrFile(srcUrl, dstUrl, newName) { //srcUrl需要移动的目录或文件,dstUrl要移动到的目标目录(父级)plus.io.resolveLocalFileSystemURL(srcUrl, function(srcEntry) {//console.log(111)plus.io.resolveLocalFileSystemURL(dstUrl, function(dstEntry) {//console.log(222)if (srcEntry.isDirectory) {//console.log(33)srcEntry.moveTo(dstEntry, newName, function(entry) {//console.log("New Path: " + entry.fullPath);return true;}, function(e) {return e;//console.log(e.message);});} else {srcEntry.moveTo(dstEntry, newName, function(entry) {//console.log("New Path: " + entry.fullPath);return true;}, function(e) {return e;//console.log(e.message);});}}, function(e) {uni.showToast({title: '获取目标目录失败:' + e.message,duration: 2000,icon: 'none'});});}, function(e) {uni.showToast({title: '获取目录失败:' + e.message,duration: 2000,icon: 'none'});});
}//创建一个新目录
function CreateNewDir(url, dirName) {//url值可支持相对路径URL、本地路径URLreturn new Promise((resolver, reject) => {plus.io.resolveLocalFileSystemURL(url, function(entry) {entry.getDirectory(dirName, {create: true,exclusive: false}, function(dir) {resolver(true)}, function(error) {reject(error.message)uni.showToast({title: dirName + '目录创建失败:' + error.message,duration: 2000,icon: 'none'});});}, function(e) {reject(error.message)uni.showToast({title: '获取目录失败:' + e.message,duration: 2000,icon: 'none'});});})
}
/*** 复制文件* @param {String} url        文件地址,文件路径,最好是相对路径 url:"_doc/...."  _doc开头* @param {String} newUrl     目标目录,最好是相对路径 url:"_doc/...."  _doc开头* @param {String} newName    拷贝后的文件名称,默认为原始文件名称*/
function copyFileTo(url, newUrl, dirName, newName) {if (url.length >= 7 && "file://" == url.substring(0, 7)) {url = url.substring(7)}let tempUrl = url.substring(0, url.lastIndexOf('/'));let addUrl = newUrl + '/' + dirName;console.log(addUrl, tempUrl)if (addUrl == tempUrl) {return url;}console.log(newUrl, dirName, newName)return new Promise((resolve, reject) => {plus.io.resolveLocalFileSystemURL(url, async (entry) => {if (entry.isFile) {let c = await CreateNewDir(newUrl, dirName)let u = await getDirsys(addUrl)entry.copyTo(u, newName, en => {resolve(en.fullPath);}, e => {console.log(e);reject('错误:复制时出现错误')uni.showModal({title: "错误",content: "复制时出现错误"})})} else {reject('错误:路径必须是文件')uni.showModal({title: "错误",content: "路径必须是文件"})}}, (e) => {console.log(e);reject(e)uni.showModal({title: "错误",content: "打开文件系统时出错"})});})
}
//获取目录对象
function getDirsys(url) {return new Promise((resolve, reject) => {plus.io.resolveLocalFileSystemURL(url, (entry) => {resolve(entry)}, (e) => {reject(e)console.log(e);});})
}
//将这些方法暴露出去
export {getJsonData,changeData,saveFile,creatDirs,moveDirectyOrFile,copyFileTo,getDirsys,
};

使用方法: 

import {getJsonData,changeData} from '@/utils/toolFile.js';//引用方法
//兼容安卓10+ (通用)- 路径最好为"_downloads/",否则在手机中找不到路径const pathUrl = plus.io.convertLocalFileSystemURL("_downloads/") +  'feature.json'//安卓10以下路径地址  安卓10+	pathUrl2  会报targetSdkVersion设置>=29后在Android10+系统设备不支持当前路径。请更改为应用运行路径 
//const pathUrl2 = '/storage/emulated/0/' + 'demo.json'/**
* 写入方法
* pathUrl - 上传路径
*  0
*  全局变量数据
*/
changeData(pathUrl, 0, data); // 读取方法
getJsonData(pathUrl).then(data=>{console.log("data",data);
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/59100.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在 VS Code 中规范化 Git 提交消息并自动生成 CHANGELOG.md

1. 使用 Commitizen 规范化 Git 提交消息 首先&#xff0c;安装 Commitizen 和适用于 Angular 提交规范的适配器&#xff1a; npm install -g commitizen commitizen init cz-conventional-changelog --save-dev --save-exact这样&#xff0c;提交信息将遵循 Angular 规范&am…

c++模板入门

c系列模板入门 文章目录 c系列模板入门一、模板概念引入二、函数模板2.1、函数模板的概念2.2、函数模板的定义格式2.3、函数模板的使用 三、类模板1.1、什么是类模板1.2、类模板的定义格式1.3、类模板于函数模板的区别 一、模板概念引入 在程序设计中我们经常需要对两个数据进…

MyBatis-Plus中AbstractJsonTypeHandler使用小结

在 MyBatis-Plus 中&#xff0c; AbstractJsonTypeHandler 是一个用于处理 JSON 数据类型的抽象类。 一、作用 1. 数据库与 Java 对象之间的 JSON 数据转换 当数据库中的字段类型为可以存储 JSON 格式数据的类型&#xff08;如 MySQL 的 JSON 类型、Oracle 的 CLOB 等可存储…

谷粒商城のsentinelzipkin

文章目录 前言一、Sentinel1、什么是Sentinel2、项目配置3、使用案例3.1、流控3.2、降级3.3、黑白名单设置 二、Zipkin1、什么是Zipkin2、项目配置3、整合案例 前言 本篇介绍Spring Cloud Ali的sentinel组件&#xff0c;用于对微服务的熔断降级&#xff0c;以及链路追踪zipkin的…

Freertos学习日志(1)-基础知识

目录 1.什么是Freertos&#xff1f; 2.为什么要学习RTOS&#xff1f; 3.Freertos多任务处理的原理 1.什么是Freertos&#xff1f; RTOS&#xff0c;即&#xff08;Real Time Operating System 实时操作系统&#xff09;&#xff0c;是一种体积小巧、确定性强的计算机操作系统…

富格林:拆穿欺诈套路平稳出金

富格林认为&#xff0c;投资者产生的欺诈亏损多半是由于被出金骗局的花言巧语所迷惑&#xff0c;以为真的躺着就可以轻轻松松赚大钱&#xff0c;结果最后发现连本金都追不回来。事实上&#xff0c;投资市场并不像大家想得那么简单&#xff0c;要想拆穿欺诈套路实现平稳出金&…

2. Flink快速上手

文章目录 1. 环境准备1.1 系统环境1.2 安装配置Java 8和Scala 2.121.3 使用集成开发环境IntelliJ IDEA1.4 安装插件2. 创建项目2.1 创建工程2.1.1 创建Maven项目2.1.2 设置项目基本信息2.1.3 生成项目基本框架2.2 添加项目依赖2.2.1 添加Flink相关依赖2.2.2 添加slf4j-nop依赖2…

TIA 中用 GSD 方式组态 ET200SP 安全模块时如何用 S7-FCT 分配安全目标地址

1 概述 用 GSD 方式组态的 ET200SP 的分布式从站上&#xff0c;现在可以使用安全模块&#xff08;早期 是无法支持&#xff09;&#xff0c;这种用法对 ET200SP 接口模块的版本和编程软件的版本都有要求。 ET200SP 故障安全模块可通过 GSD 文件用于以下接口模块&#xff1a; …

0,国产FPGA(紫光同创)-新建PDS工程

国产FPGA正在蓬勃发展&#xff0c;紫光同创FPGA是大家竞赛时经常遇到的一款国产FPGA&#xff0c;本专栏从IP核开始一直到后续图像处理等。 开发板&#xff1a;盘古50K标准板 1&#xff0c;新建PDS工程 点击File&#xff08;1&#xff09;&#xff0c;然后是New Projects&#…

【已解决】群晖docker无法删除容器 “Error response from daemon: container” 终极解决办法

【已解决】群晖docker无法删除容器终极解决办法 问题描述 DSM7.2无法通过docker rm -f删除无法通过Container Manager界面删除删除容器会报错&#xff1a;Error response from daemon: container 01eb61e74e80d49ae6273a8ca0ced196bb4be5513acce708701fe4c69cabf86e: driver…

视频Qoe测量学习笔记(一)

目录 流媒体协议详解 RTSP&#xff1a;实时流式协议 RTCP&#xff1a;实时运输控制协议 RTP&#xff1a;实时运输协议 H.264 流媒体协议详解 RTSP&#xff1a;实时流式协议 由IETF MMusic小组开发&#xff0c;已成为互联网建议标准[RFC 2326]。RTSP本身并不传送数据&…

计算机视觉常用数据集Foggy Cityscapes的介绍、下载、转为YOLO格式进行训练

我在寻找Foggy Cityscapes数据集的时候花了一番功夫&#xff0c;因为官网下载需要用公司或学校邮箱邮箱注册账号&#xff0c;等待审核通过后才能进行下载数据集。并且一开始我也并不了解Foggy Cityscapes的格式和内容是什么样的&#xff0c;现在我弄明白后写下这篇文章&#xf…

单向函数、单向陷门函数、困难问题

1、单向函数 设函数 yf(x) &#xff0c; 对于给定的x&#xff0c;计算出y很容易&#xff1b;对于给定的y&#xff0c;计算出x很难。 2、单向陷门函数 设函数 yf(x) &#xff0c;且f有陷门&#xff0c; 对于给定的x&#xff0c;计算出y很容易&#xff1b;对于给定的y&#…

前端将网页转换为pdf并支持下载与上传

1.pdf下载 handleExport() {const fixedH document.getElementById("fixed-h");const pageOne document.getElementById("mix-print-box-one");const pageTwo document.getElementById("mix-print-box-two");fixedH.style.height 30vh;pageO…

js 获取当前时间与前一个月时间

// 获取当前时间的毫秒数 var currentTimeMillis new Date().getTime();// 获取前一个月的Date对象 var dateLastMonth new Date(); dateLastMonth.setMonth(dateLastMonth.getMonth() - 1);// 获取前一个月的毫秒数 var timeMillisLastMonth dateLastMonth.getTime();conso…

Linux_02 Linux常用软件——vi、vim

vi编辑器有三种主要模式&#xff0c;每种模式的功能和用途不同&#xff1a; 一、命令模式 (Command Mode)&#xff1a; - 启动 vi 时默认进入此模式。 - 你可以在此模式下移动光标&#xff0c;输入各种命令&#xff08;如删除、复制、粘贴等&#xff09;。 yy&#xff1a;…

C++设计模式结构型模式———装饰模式

文章目录 一、引言二、装饰器模式三、总结 一、引言 装饰模式是一种结构型设计模式&#xff0c; 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。 该模式展现出了运行时的一种扩展能力&#xff0c;以及比继承更强大和灵活的设计视角和设计能力&#x…

「iOS」——知乎日报一二周总结

知乎日报仿写 前言效果Manager封装网络请求线程冲突问题下拉刷新添加网络请求的图片通过时间戳和日期格式化获取时间 总结 前言 前两周内容的仿写&#xff0c;主要完成了首页的仿写&#xff0c;进度稍慢。 效果 Manager封装网络请求 知乎日报的仿写需要频繁的申请网络请求&am…

Profinet、Ethernet/IP 工业以太网无线通信解决方案

在工业现场&#xff0c;我们常常会面临这样的困扰&#xff1a;两个PLC之间、PLC 跟远程IO之间或者PLC 跟伺服之间由于种种原因不方便布线&#xff0c;严重影响了通讯效率和生产进程。为了解决这一难题&#xff0c;三格电子设计了一款工业以太网无线网桥&#xff0c;这款无线网桥…

核心概念解析Caffeine 缓存模型与策略

1. 简介 什么是 Caffeine Caffeine 是一个高性能的 Java 缓存库&#xff0c;专为提高内存缓存的效率和灵活性而设计。它由 Google 的 Guava Cache 项目启发&#xff0c;并提供了更高的性能和更丰富的功能集。Caffeine 以其卓越的缓存命中率和内存管理能力而广受欢迎&#xff…