• 游客,欢迎来到米坛社区。
    米坛社区是大型中文智能穿戴设备交流社区,在这里交流你的极客思想,共同建造我们的智能世界
    为了更加方便的获取支持与帮助,请加入米坛社区官方QQ频道

问答 How to store values globally? How to read and write files?

ArnabXero

LV8
普通成员
UID
178095
2022-12-25
78
3,243
Hello guys, I have recently developed a racing game for Mi band 7.
Now I am trying to add a settings page where game difficulty, car speed, and other parameters will be set. After setting these parameters, I want to use them globally on other pages.

How can it be possible? Can I save the values in a text file? If yes, then how?

Or is there any way where I can save values globally?

Thanks.
 

zzt741

LV7
🔥社区作者
普通成员
UID
75550
2021-10-12
224
1,795
I suggest to store values into files, it's more stable and decrease the possibility to reboot.
here is the sample:
代码:
try {
  (() => {
 
function str2ab(str) {//add this after try
      const buf = new ArrayBuffer(str.length * 2) // 2 bytes for each char
      const bufView = new Uint16Array(buf)
      for (let i = 0, strLen = str.length; i < strLen; i++) {
        bufView[i] = str.charCodeAt(i)
      }
      return buf
    }
    class LocalStorage {
      constructor(fileName = '') {
        this.fileName = fileName
        this.contentObj = {}
      }
      set(obj) {
        const file = hmFS.open(this.fileName, hmFS.O_RDWR | hmFS.O_TRUNC)
        const contentBuffer = str2ab(JSON.stringify(obj))
        hmFS.write(file, contentBuffer, 0, contentBuffer.byteLength)
        hmFS.close(file)
      }
      get() {
        const [fsStat, err] = hmFS.stat(this.fileName)
        if (err === 0) {
          const { size } = fsStat
          const fileContentUnit = new Uint16Array(new ArrayBuffer(size))
          const file = hmFS.open(this.fileName, hmFS.O_RDONLY | hmFS.O_CREAT)
          hmFS.seek(file, 0, hmFS.SEEK_SET)
          hmFS.read(file, fileContentUnit.buffer, 0, size)
          hmFS.close(file)
          try {
            const val = String.fromCharCode.apply(null, fileContentUnit)
            this.contentObj = val ? JSON.parse(val) : {}
          } catch (error) {
            this.contentObj = {}
          }
        }
        return this.contentObj
      }
    }
    
    //---
    onDestory() {
            console.log('page onDestroy invoked')
            localStorage.set(data)//add this to onDestroy
           }
          
          //---
          const localStorage = new LocalStorage('zzt741-pet.json')//create object
          data = localStorage.get()//get file data
            if (Object.keys(data).length == 0) {//set default value, you can do this only in home page
              data = {
                whaleCount: 0,
                resurgenceCount: 0
              }
              let var1=data.whaleCount //get data
              data.whaleCount=var1 //set data
 
  • 赞
反馈: ArnabXero

bbComputerdd

LV5
普通成员
UID
118799
2022-09-03
33
591
I suggest to store values into files, it's more stable and decrease the possibility to reboot.
here is the sample:
代码:
try {
  (() => {
 
function str2ab(str) {//add this after try
      const buf = new ArrayBuffer(str.length * 2) // 2 bytes for each char
      const bufView = new Uint16Array(buf)
      for (let i = 0, strLen = str.length; i < strLen; i++) {
        bufView[i] = str.charCodeAt(i)
      }
      return buf
    }
    class LocalStorage {
      constructor(fileName = '') {
        this.fileName = fileName
        this.contentObj = {}
      }
      set(obj) {
        const file = hmFS.open(this.fileName, hmFS.O_RDWR | hmFS.O_TRUNC)
        const contentBuffer = str2ab(JSON.stringify(obj))
        hmFS.write(file, contentBuffer, 0, contentBuffer.byteLength)
        hmFS.close(file)
      }
      get() {
        const [fsStat, err] = hmFS.stat(this.fileName)
        if (err === 0) {
          const { size } = fsStat
          const fileContentUnit = new Uint16Array(new ArrayBuffer(size))
          const file = hmFS.open(this.fileName, hmFS.O_RDONLY | hmFS.O_CREAT)
          hmFS.seek(file, 0, hmFS.SEEK_SET)
          hmFS.read(file, fileContentUnit.buffer, 0, size)
          hmFS.close(file)
          try {
            const val = String.fromCharCode.apply(null, fileContentUnit)
            this.contentObj = val ? JSON.parse(val) : {}
          } catch (error) {
            this.contentObj = {}
          }
        }
        return this.contentObj
      }
    }
   
    //---
    onDestory() {
            console.log('page onDestroy invoked')
            localStorage.set(data)//add this to onDestroy
           }
         
          //---
          const localStorage = new LocalStorage('zzt741-pet.json')//create object
          data = localStorage.get()//get file data
            if (Object.keys(data).length == 0) {//set default value, you can do this only in home page
              data = {
                whaleCount: 0,
                resurgenceCount: 0
              }
              let var1=data.whaleCount //get data
              data.whaleCount=var1 //set data
大佬,请问hmFS.read读取到ArrayBuffer中的内容如何转换成string
孩子整不明白了,求救。问题代码如下:
JavaScript:
const language = hmSetting.getLanguage();
let fileId, filename, errRd;
switch (language) {
    case 0:
        filename = "voiceoversc.txt";
        break;
    case 1:
        filename = "voiceovertc.txt";
        break;
    case 2:
        filename = "voiceoveren.txt"; //3个文件均采用utf-8编码
        break;
}
fileId = hmFS.open(filename, hmFS.O_RDONLY | hmFS.O_CREAT);
const [fs_stat, err] = hmFS.stat_asset(filename);
const { size } = fs_stat;
let res, arr = new Uint8Array(new ArrayBuffer(size)), voiceover = [];
if (err == 0) {
    errRd = hmFS.read(fileId, arr.buffer, 0, size);
    hmFS.close(fileId);
    if (errRd == 0) {
        res = decodeURIComponent(escape(String.fromCharCode.apply(null, arr)));// 模拟器显示正常 刷入米环7后没有正确解码出内容
        // String.fromCharCode.apply(null, arr), escape(String.fromCharCode.apply(null, arr)), decodeURIComponent(String.fromCharCode.apply(null, arr))均无效
        for (let i = 0, tmp = ""; i < res.length; i++) {
            if (res[i] != "\n") { // voiceover__.txt must use LF line ending!
                tmp += res[i];
            } else {
                voiceover.push(tmp);
                tmp = "";
            }
        }
    }
}
 

zzt741

LV7
🔥社区作者
普通成员
UID
75550
2021-10-12
224
1,795
大佬,请问hmFS.read读取到ArrayBuffer中的内容如何转换成string
孩子整不明白了,求救。问题代码如下:
JavaScript:
const language = hmSetting.getLanguage();
let fileId, filename, errRd;
switch (language) {
    case 0:
        filename = "voiceoversc.txt";
        break;
    case 1:
        filename = "voiceovertc.txt";
        break;
    case 2:
        filename = "voiceoveren.txt"; //3个文件均采用utf-8编码
        break;
}
fileId = hmFS.open(filename, hmFS.O_RDONLY | hmFS.O_CREAT);
const [fs_stat, err] = hmFS.stat_asset(filename);
const { size } = fs_stat;
let res, arr = new Uint8Array(new ArrayBuffer(size)), voiceover = [];
if (err == 0) {
    errRd = hmFS.read(fileId, arr.buffer, 0, size);
    hmFS.close(fileId);
    if (errRd == 0) {
        res = decodeURIComponent(escape(String.fromCharCode.apply(null, arr)));// 模拟器显示正常 刷入米环7后没有正确解码出内容
        // String.fromCharCode.apply(null, arr), escape(String.fromCharCode.apply(null, arr)), decodeURIComponent(String.fromCharCode.apply(null, arr))均无效
        for (let i = 0, tmp = ""; i < res.length; i++) {
            if (res[i] != "\n") { // voiceover__.txt must use LF line ending!
                tmp += res[i];
            } else {
                voiceover.push(tmp);
                tmp = "";
            }
        }
    }
}
我的示例代码中文件使用的是utf-16 LE编码,建议使用这种编码,解码更简单,
如果要用utf-8,可以使用melianmiko的工具箱中的函数:
JavaScript:
    function decodeUtf8(array, outLimit = Infinity, startPosition = 0) {
        let out = "";
        let length = array.length;
        let i = startPosition, c, char2, char3;
        while (i < length && out.length < outLimit) {
            c = array[i++];
            switch (c >> 4) {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                    out += String.fromCharCode(c);
                    break;
                case 12:
                case 13:
                    char2 = array[i++];
                    out += String.fromCharCode(
                        (c & 31) << 6 | char2 & 63
                    );
                    break;
                case 14:
                    char2 = array[i++];
                    char3 = array[i++];
                    out += String.fromCharCode(
                        (c & 15) << 12 | (char2 & 63) << 6 | (char3 & 63) << 0
                    );
                    break;
            }
        }
        return [out, i - startPosition];
    }


调用方式:
                    const [fsStat, err] = hmFS.stat(path)
                    if (err != 0) {
                        hmUI.showToast({ text: "读取出错!" })
                    }
                    const buffer = new ArrayBuffer(fsStat.size)
                    const file = hmFS.open(path, hmFS.O_RDONLY)
                    hmFS.read(file, buffer, 0, fsStat.size)
                    hmFS.close(file)
                    const arr = new Uint8Array(buffer);
                    let text = decodeUtf8(arr)[0]
 

bbComputerdd

LV5
普通成员
UID
118799
2022-09-03
33
591
我的示例代码中文件使用的是utf-16 LE编码,建议使用这种编码,解码更简单,
如果要用utf-8,可以使用melianmiko的工具箱中的函数:
JavaScript:
    function decodeUtf8(array, outLimit = Infinity, startPosition = 0) {
        let out = "";
        let length = array.length;
        let i = startPosition, c, char2, char3;
        while (i < length && out.length < outLimit) {
            c = array[i++];
            switch (c >> 4) {
                case 0:
                case 1:
                case 2:
                case 3:
                case 4:
                case 5:
                case 6:
                case 7:
                    out += String.fromCharCode(c);
                    break;
                case 12:
                case 13:
                    char2 = array[i++];
                    out += String.fromCharCode(
                        (c & 31) << 6 | char2 & 63
                    );
                    break;
                case 14:
                    char2 = array[i++];
                    char3 = array[i++];
                    out += String.fromCharCode(
                        (c & 15) << 12 | (char2 & 63) << 6 | (char3 & 63) << 0
                    );
                    break;
            }
        }
        return [out, i - startPosition];
    }


调用方式:
                    const [fsStat, err] = hmFS.stat(path)
                    if (err != 0) {
                        hmUI.showToast({ text: "读取出错!" })
                    }
                    const buffer = new ArrayBuffer(fsStat.size)
                    const file = hmFS.open(path, hmFS.O_RDONLY)
                    hmFS.read(file, buffer, 0, fsStat.size)
                    hmFS.close(file)
                    const arr = new Uint8Array(buffer);
                    let text = decodeUtf8(arr)[0]
大佬,用了您给的方法后,手环实机上text还是原始的字节流(text.length返回的数值=原始文件的字节数,而不是实际字符数)
文本文件换用utf-16le后,按照您3楼的方法,text.length返回了期望的数值,但解码出的结果全部是0x0NULL
而以上两种情况在模拟器上均没有出现,也无法复现(应该吧)。
再帮一把孩子谢谢,如何解决,感激不尽
 

zzt741

LV7
🔥社区作者
普通成员
UID
75550
2021-10-12
224
1,795
utf-8那个我自己试过读取应用的json文件是没有问题的啊,你试着有显示出来吗?
utf16le的话有个坑忘了讲,如果是读取外界写入的文件的话,需要跳过2字节,因为开头2字节是标记编码的,试试这个:
const [fsStat, err] = hmFS.stat_asset("config.txt")
let config
if (err === 0) {
const fileContentUnit = new Uint16Array(new ArrayBuffer(fsStat.size - 2))
const file = hmFS.open_asset("config.txt", hmFS.O_RDONLY | hmFS.O_CREAT)
hmFS.seek(file, 2, hmFS.SEEK_SET)
hmFS.read(file, fileContentUnit.buffer, 0, fsStat.size - 2)
hmFS.close(file)
config = String.fromCharCode.apply(null, fileContentUnit)
config = JSON.parse(config)
} else {
hmUI.showToast({ text: "读取文件失败!" + err })
}
 

bbComputerdd

LV5
普通成员
UID
118799
2022-09-03
33
591
utf-8那个我自己试过读取应用的json文件是没有问题的啊,你试着有显示出来吗?
utf16le的话有个坑忘了讲,如果是读取外界写入的文件的话,需要跳过2字节,因为开头2字节是标记编码的,试试这个:
解决了 谢谢大佬
 

*这是一则由 Google AdSense 自动推荐的广告,与本站无关,不对其真实性与可靠性负责