Auto.js 入门指南(十三)数据存储与本地持久化

前言

大家好,我是鲫小鱼。是一名不写前端代码的前端工程师,热衷于分享非前端的知识,带领切图仔逃离切图圈子,欢迎关注我,微信公众号:《鲫小鱼不正经》。欢迎点赞、收藏、关注,一键三连!!

第十三章:数据存储与本地持久化


一、理论讲解:本地存储方式与原理

1.1 为什么需要本地存储?

  • 持久化用户数据、脚本配置、历史记录、缓存内容
  • 离线场景下数据可用,提升用户体验
  • 支持数据同步、备份、迁移、恢复

1.2 常见本地存储方式

  • 文件存储(files 模块):文本、JSON、二进制、图片、日志等
  • 键值存储(storage 模块):轻量级配置、状态、缓存
  • 数据库存储(sqlite):结构化数据、批量数据、复杂查询
  • 缓存机制:内存缓存、磁盘缓存、定期清理
  • 加密存储:敏感信息加密、Token、账号密码

1.3 存储原理与适用场景

  • 文件系统:适合大文件、日志、图片、批量数据
  • 键值对:适合配置、状态、少量数据
  • 数据库:适合结构化、复杂、多表数据
  • 缓存:适合高频、临时、可丢弃数据

二、代码示例:Auto.js 本地存储全场景实战

2.1 文件读写(文本/JSON/二进制/图片)

javascript 复制代码
// 写入文本文件
files.write("/sdcard/demo.txt", "Hello, Auto.js!");
// 读取文本文件
var txt = files.read("/sdcard/demo.txt");
log("读取内容:" + txt);

// 写入 JSON 文件
var data = { user: "fish", time: Date.now() };
files.write("/sdcard/data.json", JSON.stringify(data, null, 2));
// 读取 JSON 文件
var obj = JSON.parse(files.read("/sdcard/data.json"));
log("用户:" + obj.user);

// 写入二进制文件(如图片)
if(requestScreenCapture()){
    var img = captureScreen();
    images.save(img, "/sdcard/screenshot.png");
    toast("截图已保存");
}
// 读取图片
var img2 = images.read("/sdcard/screenshot.png");
if(img2) toast("图片读取成功");

2.2 文件追加、批量写入与分批处理

javascript 复制代码
// 追加日志
files.append("/sdcard/log.txt", new Date().toLocaleString() + " 脚本启动\n");

// 批量写入数据
var arr = [];
for(let i=0;i<100;i++) arr.push({id:i, time:Date.now()});
files.write("/sdcard/batch.json", JSON.stringify(arr));

// 分批写入大数据
function writeInBatches(data, batchSize, filePath){
    for(let i=0;i<data.length;i+=batchSize){
        let batch = data.slice(i, i+batchSize);
        files.append(filePath, JSON.stringify(batch) + "\n");
    }
}
writeInBatches(arr, 20, "/sdcard/batch.log");

2.3 文件遍历、删除与清理

javascript 复制代码
// 遍历目录下所有文件
files.listDir("/sdcard/", function(name){
    log("文件:" + name);
});

// 删除文件
if(files.exists("/sdcard/demo.txt")) files.remove("/sdcard/demo.txt");

// 清理目录
function clearDir(dir){
    files.listDir(dir, function(name){
        files.remove(files.join(dir, name));
    });
}
clearDir("/sdcard/temp");

2.4 键值存储(storage 模块)

javascript 复制代码
// 创建/获取 storage
var store = storages.create("my_config");
// 写入键值
store.put("token", "abc123");
// 读取键值
var token = store.get("token", "");
log("Token:" + token);
// 删除键值
store.remove("token");
// 清空所有数据
store.clear();

2.5 数据库存储(sqlite)

javascript 复制代码
// 打开数据库
var db = SQLiteDatabase.openOrCreateDatabase("/sdcard/demo.db", null);
// 创建表
db.execSQL("CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY, name TEXT, time INTEGER)");
// 插入数据
for(let i=0;i<10;i++){
    db.execSQL("INSERT INTO user (name, time) VALUES (?, ?)", ["fish"+i, Date.now()]);
}
// 查询数据
var cursor = db.rawQuery("SELECT * FROM user", null);
while(cursor.moveToNext()){
    log("用户:" + cursor.getString(1) + ", 时间:" + cursor.getLong(2));
}
cursor.close();
db.close();

2.6 配置文件读写与自动备份

javascript 复制代码
// 读写配置文件
var config = { interval: 10, autoStart: true };
files.write("/sdcard/config.json", JSON.stringify(config));
var conf = JSON.parse(files.read("/sdcard/config.json"));
log("配置:" + JSON.stringify(conf));

// 自动备份
function backupFile(src, dest){
    if(files.exists(src)) files.copy(src, dest);
}
backupFile("/sdcard/data.json", "/sdcard/backup/data_bak.json");

2.7 加密存储与敏感信息保护

javascript 复制代码
// 简单加密存储(Base64)
function encodeBase64(str){
    return java.util.Base64.getEncoder().encodeToString(java.lang.String(str).getBytes());
}
function decodeBase64(str){
    return java.lang.String(java.util.Base64.getDecoder().decode(str));
}
var secret = encodeBase64("my_password");
files.write("/sdcard/secret.txt", secret);
var pwd = decodeBase64(files.read("/sdcard/secret.txt"));
log("解密后密码:" + pwd);

2.8 缓存机制与数据同步

javascript 复制代码
// 简单内存缓存
var cache = {};
function setCache(key, value){ cache[key] = value; }
function getCache(key){ return cache[key]; }

// 磁盘缓存(如图片)
function cacheImage(url, path){
    if(!files.exists(path)){
        var res = http.get(url);
        if(res.statusCode==200) files.writeBytes(path, res.body.bytes());
    }
    return images.read(path);
}

// 数据同步
function syncLocalToRemote(localPath, remoteUrl){
    var data = files.read(localPath);
    http.post(remoteUrl, { data });
}

2.9 数据清理与定期维护

javascript 复制代码
// 定期清理日志
function cleanOldLogs(dir, days){
    var now = Date.now();
    files.listDir(dir, function(name){
        var path = files.join(dir, name);
        if(files.isFile(path)){
            var last = files.lastModified(path);
            if(now - last > days*24*3600*1000) files.remove(path);
        }
    });
}
cleanOldLogs("/sdcard/logs", 7);

2.10 移动端适配与多设备兼容

javascript 复制代码
// 获取存储路径
var sdPath = files.getSdcardPath();
log("SD卡路径:" + sdPath);

// 判断文件/目录是否存在
if(files.exists(sdPath+"/autojs")) log("目录存在");

// 兼容不同 Android 版本
if(device.sdkInt >= 30){
    log("Android 11+,需适配分区存储");
}

三、实战项目:自动记录签到历史与本地缓存工具

3.1 项目需求

  • 自动记录每次签到结果到本地 JSON 文件
  • 支持历史查询、导出、清理、备份
  • 支持缓存常用数据,提升性能
  • 支持数据同步与恢复

3.2 项目结构

plaintext 复制代码
autojs-datastore/
├── main.js
├── modules/
│   ├── datastore.js
│   └── logger.js
├── data/
│   └── history.json
├── backup/
│   └── history_bak.json
├── logs/
│   └── data.log
└── README.md

3.3 datastore.js 数据存储模块

javascript 复制代码
// modules/datastore.js
function saveHistory(record){
    var path = "../data/history.json";
    var arr = files.exists(path) ? JSON.parse(files.read(path)) : [];
    arr.push(record);
    files.write(path, JSON.stringify(arr, null, 2));
}
function getHistory(){
    var path = "../data/history.json";
    if(files.exists(path)) return JSON.parse(files.read(path));
    return [];
}
function clearHistory(){
    files.write("../data/history.json", "[]");
}
function backupHistory(){
    files.copy("../data/history.json", "../backup/history_bak.json");
}
module.exports = { saveHistory, getHistory, clearHistory, backupHistory };

3.4 main.js 主流程

javascript 复制代码
// main.js
const ds = require("./modules/datastore.js");
const logger = require("./modules/logger.js");

// 新增签到记录
var record = { user: "fish", time: Date.now(), status: "success" };
ds.saveHistory(record);
logger.log("签到记录已保存");

// 查询历史
var history = ds.getHistory();
history.forEach(r => logger.log(JSON.stringify(r)));

// 备份历史
ds.backupHistory();
logger.log("历史已备份");

// 清理历史
// ds.clearHistory();
// logger.log("历史已清空");

3.5 logger.js 日志模块

javascript 复制代码
// modules/logger.js
function log(msg) {
    let line = `[${new Date().toLocaleTimeString()}] ${msg}`;
    files.append("../logs/data.log", line + "\n");
    toast(msg);
}
module.exports = { log };

3.6 history.json 示例

json 复制代码
[
  { "user": "fish", "time": 1710000000000, "status": "success" },
  { "user": "cat", "time": 1710000001000, "status": "fail" }
]

四、常见问题与解决方案

问题 解决方案
文件读写失败/权限不足 检查存储权限、路径、Android 版本适配
JSON 解析报错/数据丢失 检查数据格式、加 try-catch、备份恢复
数据库操作异常/表不存在 检查 SQL 语句、表结构、路径
键值存储丢失/覆盖 检查 key 命名、加锁、分批写入
批量写入卡顿/内存溢出 分批处理、异步写入、优化数据结构
缓存失效/数据不同步 优化缓存逻辑、定期同步、加日志
加密存储解密失败 检查加密算法、密钥、数据格式
备份失败/恢复异常 检查文件路径、权限、备份逻辑
数据清理误删/恢复困难 增加确认、备份、日志记录
多设备兼容性问题 适配不同 Android 版本、存储路径、分区存储
数据同步冲突/覆盖 加锁、队列、分片处理,避免并发写入
目录遍历慢/卡顿 优化遍历逻辑、异步处理、分页加载
图片/二进制文件损坏 检查写入逻辑、加校验、异常处理

五、性能优化建议

  • 批量/分批写入,避免一次性大数据操作
  • 合理缓存数据,减少磁盘读写
  • 日志分级输出,便于排查问题
  • 异步处理耗时操作,主线程只做调度
  • 定期清理无用数据,释放存储空间
  • 数据加密压缩,提升安全与效率
  • 备份与恢复机制,防止数据丢失
  • 适配不同 Android 版本与分区存储
  • 合理 sleep,避免无效等待
  • 及时释放资源,防止内存泄漏
  • 关键节点加详细日志,便于追踪
  • 目录遍历/数据加载分页处理,提升流畅度
  • 适配移动端存储波动,自动切换路径

最后感谢阅读!欢迎关注我,微信公众号:《鲫小鱼不正经》。欢迎点赞、收藏、关注,一键三连!!!

相关推荐
mldong29 分钟前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排1 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60612 小时前
如何自己造一个时间处理库
前端·javascript·github
flower_drop2 小时前
基于 WebUSB 与 CDP:在浏览器端实现 Android 设备通信与无证书抓包实践
android·chrome·测试工具·adb·bug·edge浏览器
走到天涯海角3 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!3 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰3 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
撩得Android一次心动4 小时前
Jetpack Compose 知识点整理1【个人用】
android·学习·kotlin·android jetpack·compose
mayaairi5 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen5 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能