Autojs: 坚果云 文件上传/下载

本文介绍了一个用于坚果云的SDK实现,该SDK支持文件的上传、下载、删除等操作,并提供了详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

例子

// http 请求在 "ui 线程" 执行, 会报错 "NetworkOnMainThreadException"
// 所以这里需要开启多线程, 
// 如果你的脚本顶部没有 "ui" 则不需要开启新线程
threads.start(() => {

  // 初始化 ( "我的坚果云" 是坚果云自带的文件夹,使用时建议改为别的名称 )
  let jgy = new JianGuoYunUtil("账户", "应用密码", "我的坚果云");
  
  let file_path = "/sdcard/A_My_DB/sqlite.db";
  
  // 读取文件 ( byte[] )
  let byteData = files.readBytes(file_path);
  
  // 上传文件 (各种文件都可以)
  let r = jgy.putFile(byteData, "sqlite.db");
  
  console.log(r.isSuccess);

  // https://www.jianguoyun.com/#/
  // 坚果云 自带文件历史,可以手动到网页中 下载或恢复 历史版本
  
  // 下载文件
  let r2 = jgy.getFile("sqlite.db")
  if (r2.isSuccess) {  
    // writeBytes 会覆盖文件,
    // 可以提前使用 files.copy 将文件备份一个, 文件名追加当前时间用于区分
    console.log(r2.msg.length); // 文件大小    
    files.writeBytes(file_path, r2.msg) // 保存文件    
  }  

  //---

  // 设置后,下面再调用相关函数就不用传文件名了
  jgy.setThisFileName("demo", "txt")
  
  // 上传文本 ( 直接保存文字,不需要读取文件再上传, 常用来保存 json 数据 )
  jgy.putText("哈哈哈")
  
  // 获取文本
  console.log(jgy.getText());
  
  // 获取目录的文件列表
  console.log(jgy.getFolderCatalog());
});

在这里插入图片描述

代码

/**
 * 坚果云 文件 上传/下载
 *
 * 常用来备份 SQLite 数据库, 多设备共享某个文件
 */
var JianGuoYunUtil = /** @class */ (function () {

    /**
     * 初始化
     *
     * 账户和密码到官网创建 https://www.jianguoyun.com/#/safety
     * @param username 账户
     * @param password 应用密码
     * @param folderName 文件夹名称
     */
    function JianGuoYunUtil(username, password, folderName) {
        this.fileName = "";
        this.folderName = folderName;
        this.jgyHost = "https://dav.jianguoyun.com/dav/" + this.folderName + "/";
        this.authorizationStr = "Basic " + this.__getBase64(username + ":" + password);
        this.header = {
            "Authorization": this.authorizationStr,
        };
        this.headerWithText = {
            "Authorization": this.authorizationStr,
            "Content-Type": "text/plain;charset=UTF-8",
        };
        this.__createFolder();
    }
    
    /**
     * 设置 操作的 fileName, 之后的方法不再需要传 fileName
     * @param {string} fileName
     * @param {string?} fileExtension 可空, 默认 "txt"
     */
    JianGuoYunUtil.prototype.setThisFileName = function (fileName, fileExtension) {
        if (fileExtension == void 0) {
            fileExtension = "txt";
        }
        this.fileName = fileName + "." + fileExtension;
    };
    
    /**
     * 读取文件夹的目录
     * @returns {string[]}
     */
    JianGuoYunUtil.prototype.getFolderCatalog = function () {
        var httpResp = http.request(this.jgyHost, {
            method: "PROPFIND",
            headers: this.header,
        });
        var retArr = [];
        var xmlData = httpResp.body.string();
        if (xmlData) {
            var dataArr = xmlData.match(/<d:displayname>(.*?)<\/d:displayname>/g);
            for (var _i = 0, _a = dataArr !== null && dataArr !== void 0 ? dataArr : []; _i < _a.length; _i++) {
                var item = _a[_i];
                item = item.replace("<d:displayname>", "").replace("</d:displayname>", "");
                if (item != this.folderName) {
                    retArr.push(item);
                }
            }
        }
        return retArr;
    };
    
    /**
     * 创建文件夹
     * @returns {boolean}
     */
    JianGuoYunUtil.prototype.__createFolder = function () {
        var httpResp = http.request(this.jgyHost, {
            method: "MKCOL",
            headers: this.header,
        });
        return httpResp.statusCode == 201;
    };
    JianGuoYunUtil.prototype.__getThisFileName = function (fileName) {
        // 参数有值则直接返回
        // 为空则取类变量,
        if (fileName == undefined) {
            // 类变量不为空,则返回类变量,否则抛出异常
            if (this.fileName != "") {
                fileName = this.fileName;
            }
            else {
                throw "当前必须传 fileName, 调用 setThisFileName 后,才可以不传 fileName";
            }
        }
        return fileName;
    };
    
    /**
     * 删除一个文件
     * @param {string?} fileName 可空, 需要提前调用 setThisFileName
     */
    JianGuoYunUtil.prototype.delete = function (fileName) {
        var ret = { isSuccess: false, msg: "删除失败" };
        try {
            fileName = this.__getThisFileName(fileName);
            var fileArr = this.getFolderCatalog();
            if (fileArr.indexOf(fileName) > -1) {
                http.request(this.jgyHost + fileName, {
                    method: "DELETE",
                    headers: this.header,
                });
                fileArr = this.getFolderCatalog();
                if (fileArr.indexOf(fileName) < 0) {
                    ret.isSuccess = true;
                    ret.msg = "删除成功";
                }
                else {
                    ret.msg = "删除失败,文件依然在目录中";
                }
            }
            else {
                ret.isSuccess = true;
                ret.msg = "文件不存在,无需删除";
            }
        }
        catch (error) {
            ret.msg = error;
        }
        return ret;
    };
    
    /**
     * 获取 文本内容
     * @param {string?} fileName 可空, 需要提前调用 setThisFileName
     */
    JianGuoYunUtil.prototype.getText = function (fileName) {
        return this.downLoadFile(false, fileName);
    };
    
    /**
      * 获取 byte[] 内容
      * @param {string?} fileName 可空, 需要提前调用 setThisFileName
      */
    JianGuoYunUtil.prototype.getFile = function (fileName) {
        return this.downLoadFile(true, fileName);
    };
    
    /**
     * 上传文件 ( string )
     * @param {string} data 字符串内容
     * @param {string?} fileName 可空, 需要提前调用 setThisFileName
     */
    JianGuoYunUtil.prototype.putText = function (data, fileName) {
        var ret = { isSuccess: false, msg: "上传失败" };
        try {
            fileName = this.__getThisFileName(fileName);
            var httpResp = http.request(this.jgyHost + fileName, {
                method: "PUT",
                headers: this.headerWithText,
                body: data,
            });
            if (httpResp.statusCode == 201 || httpResp.statusCode == 204) {
                ret.isSuccess = true;
                ret.msg = "本地数据 上传到 坚果云 成功";
            }
        }
        catch (error) {
            ret.msg = error;
        }
        return ret;
    };
    
    /**
     * 下载文件
     * @param {boolean} isByteData true 返回 byte[], false 返回 string
     * @param {string?} fileName 可空, 需要提前调用 setThisFileName
     */
    JianGuoYunUtil.prototype.downLoadFile = function (isByteData, fileName) {
        var ret = { isSuccess: false, msg: "获取失败" };
        try {
            fileName = this.__getThisFileName(fileName);
            var httpResp = http.get(this.jgyHost + fileName, {
                headers: this.header,
            });
            if (httpResp.statusCode == 404) {
                var strRes = httpResp.body.string();
                if (strRes.indexOf("doesn't exist") > -1 || strRes.indexOf("The file was deleted") > -1) {
                    ret.msg = "没有文件:" + fileName;
                }
            }
            else if (httpResp.statusCode == 200) {
                ret.isSuccess = true;
                if (isByteData) {
                    ret.msg = httpResp.body.bytes();
                }
                else {
                    ret.msg = httpResp.body.string();
                }
            }
            else {
                ret.msg = "未知的状态码:" + httpResp.statusCode;
            }
        }
        catch (error) {
            ret.msg = "异常信息:" + JSON.stringify(error);
        }
        return ret;
    };
    
    /**
     * 上传文件  ( byte[] )
     *
     * 覆盖文件后, 坚果云有 "文件历史", 可以恢复到任意版本
     * @param byteData 字节数组 ( files.readBytes(file_path) )
     * @param fileName  可空, 需要提前调用 setThisFileName
     * @returns
     */
    JianGuoYunUtil.prototype.putFile = function (byteData, fileName) {
        var ret = { isSuccess: false, msg: "上传失败" };
        try {
            fileName = this.__getThisFileName(fileName);
            importPackage(Packages["okhttp3"]);
            importClass(com.stardust.autojs.core.http.MutableOkHttp);
            // aj 封装的 http 有 bug, 会报错 ( 底层也是 okhttp ),
            // 所以这里自己调用 okhttp
            var client = new MutableOkHttp();
            var mediaType = MediaType.parse("application/octet-stream");
            var requestBody = RequestBody.create(mediaType, byteData);
            var request = new Request.Builder()
                .url(this.jgyHost + fileName)
                .put(requestBody)
                .header("Authorization", this.authorizationStr)
                .header("Content-Type", "application/octet-stream")
                .header("Content-Length", byteData.length) // 设置文件大小
                .build();
            // 发送
            var response = client.newCall(request).execute();
            // console.log(Object.keys(response));
            // console.log(response.code());
            // 201 创建 / 204 覆盖
            if (response.code() == "201" || response.code() == "204") {
                ret.isSuccess = true;
                ret.msg = "本地数据 上传到 坚果云 成功";
            }
        }
        catch (error) {
            ret.msg = error;
        }
        return ret;
    };
    
    /**
     * 获取 base64 结果
     * @param {string} str
     * @returns {string}
     */
    JianGuoYunUtil.prototype.__getBase64 = function (str) {
        return java.lang.String(android.util.Base64.encode(java.lang.String(str).getBytes(), 2));
    };
    
    return JianGuoYunUtil;
}());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值