起因
原ATRI文本文件大小为1.6MB,而watch gt这破表加载300KB的文本文件时,不管是import的形式,还是storage的形式,亦或是file.read的形式,都会卡到重启。
于是,在此背景下研究了一个分块加载文本的代码格式
举个例子
我有如下一个json的文本列表,我就会在达到某一个条件时加载其中符合条件的那个。
PS:之前试过使用require分块加载,但是还是会报错,不知道是系统原因还是啥原因,人家小米全import加载都不会报错(
jsonDataList: [
'b999.json', 'b101.json', 'b102.json', 'b103.json', 'b111.json', 'b112.json', 'b113.json', 'b114.json',
'b121.json', 'b122.json', 'b123.json', 'b124.json', 'b200.json', 'b201.json', 'b202.json', 'b203.json',
'b204.json', 'b205.json', 'b206.json', 'b207.json', 'b301.json', 'b302.json', 'b303.json', 'b304.json',
'b401.json', 'b402.json', 'b403.json', 'b404.json', 'b405.json', 'b406.json', 'b407.json', 'b501.json',
'b601.json', 'b701.json'
],
如下代码为ATRI加载文本文件使用的方法
PS:原计划是将文本放在本地的,但是我不会读取读取本地文件,开发文档也没讲,寄!
async loadData(chapter) {
const num = this.jsonDataList[chapter];
// 将回调转换为Promise
return new Promise((resolve, reject) => {
file.readText({
uri: `internal://files/${num}`,
success: (data) => {
try {
const parsedData = JSON.parse(data.text);
resolve(parsedData); // 正确传递解析后的数据
} catch (e) {
reject("JSON解析失败");
}
},
fail: (_, code) => {
reject(`文件读取失败,错误码:${code}`);
}
});
});
},
最近在做一个可查找的词典,但是由于词库过大,加载200KB的索引会卡死,于是将索引分为26份,按照首字母(全部转化为小写)进行查找,不必将所有索引全部加载,实现按需查找的功能,并且也不会爆内存,完美!
下面给出我写的下载模块,因为watch gt不支持数据块传输,所以只能使用全部下载字节流的方式了:
import fetch from '@blueos.network.fetch'
import file from '@blueos.storage.file'
import prompt from '@blueos.window.prompt'
export default {
data: {
indexData: null,
jsonDataList: ['output_part_1.json'],
},
async fetchPromise(options) {
return new Promise((resolve, reject) => {
fetch.fetch({
...options,
success: resolve,
fail: reject,
});
});
},
async writeTextPromise(options) {
return new Promise((resolve, reject) => {
file.writeText({
...options,
success: resolve,
fail: (data, code) => reject({ data, code }),
});
});
},
async writeArrayBufferPromise(options) {
return new Promise((resolve, reject) => {
file.writeArrayBuffer({
...options,
success: resolve,
fail: (data, code) => reject({ data, code }),
});
});
},
async getFile(fileName) {
return new Promise((resolve, reject) => {
file.get({
uri: `internal://files/${fileName}`,
success: () => {
resolve(true);
},
fail: (_, code) => {
reject(`handling fail, code = ${code}`);
},
});
});
},
async downloadFile(data) {
prompt.showToast({ message: "开始下载" });
let totalNum = data.length;
let hasDownload = 0;
for (let i = 0; i < totalNum; i++) {
const fileName = data[i];
let isInFile = false;
try {
isInFile = await this.getFile(fileName);
} catch (error) {
console.log(error);
}
if (isInFile) hasDownload++;
if (!isInFile) {
try {
let fileUri = `internal://files/${fileName}`;
let baseUrl = 'https://chorblack.top'
const chunkResponse = await this.fetchPromise({
url: `${baseUrl}/app/dictionary/${fileName}`,
responseType: "arraybuffer",
});
const textData = chunkResponse.data;
await this.writeArrayBufferPromise({
uri: fileUri,
buffer: new Uint8Array(textData),
});
prompt.showToast({
message: `还剩${data.length - i - 1}`
})
hasDownload++;
} catch (error) {
console.error(`下载失败: ${fileName}`, error);
}
}
}
if (hasDownload==totalNum) prompt.showToast({ message: "下载完成" });
}
}