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,避免无效等待
  • 及时释放资源,防止内存泄漏
  • 关键节点加详细日志,便于追踪
  • 目录遍历/数据加载分页处理,提升流畅度
  • 适配移动端存储波动,自动切换路径

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

相关推荐
Carlos_sam21 分钟前
OpenLayers:封装一个自定义罗盘控件
前端·javascript
前端南玖31 分钟前
深入Vue3响应式:手写实现reactive与ref
前端·javascript·vue.js
wordbaby1 小时前
React Router 双重加载器机制:服务端 loader 与客户端 clientLoader 完整解析
前端·react.js
itslife1 小时前
Fiber 架构
前端·react.js
3Katrina1 小时前
妈妈再也不用担心我的课设了---Vibe Coding帮你实现期末课设!
前端·后端·设计
hubber1 小时前
一次 SPA 架构下的性能优化实践
前端
用户2018792831671 小时前
通俗易懂的讲解:Android系统启动全流程与Launcher诞生记
android
二流小码农1 小时前
鸿蒙开发:资讯项目实战之项目框架设计
android·ios·harmonyos
可乐只喝可乐2 小时前
从0到1构建一个Agent智能体
前端·typescript·agent
Muxxi2 小时前
shopify模板开发
前端