HarmonyOS 超长JSON字符串解析

在实际的项目中将后台配置的JSON字符串下载在手机中(其他系统是用的SP存储)然后进行解析,拿到里面的内容。

在HarmonyOS 中,初期计划下载下来用首选项进行存储,但了解到首选项存储不料这么长的字符串。所以存储成了文件。

当前困难影响:

在获取文件中内容 时,我定义了

@State jsGlobalConfig:string=''

在while中来进行接收

this.jsGlobalConfig = this.jsGlobalConfig+value.toString()

但报错了:

[nodict][common_func.cpp:122->GetActualLen] Invalid option.length
[nodict][common_func.cpp:371->GetReadArg] Failed to get actual length
[nodict][prop_n_exporter.cpp:388->ReadSync] Failed to resolve buf and options
 [nodict][ecmascript] Pending exception before IsMixedDebugEnabled called in line:3320, exception details as follows:
 [nodict]Error: Invalid argument
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

不知道是因为string的长度有限,不能存储太长的字符串还是因为什么。

1、我应该用什么来接收超长JSON字符串

2、如何进行解析,拿到里面的数据。

以下是我们项目中的部分解析代码。

String jsGlobalConfig = “实际获取到的超长JSON字符串”
JSONObject jsonObject = new JSONObject(jsGlobalConfig);
JSONArray pagesArray = jsonObject.optJSONArray("pages");
String pathname = getUrlSubstring(pathName);

String matchUrl = "";

for (int i = 0; i < pagesArray.length(); i++) {
  if (pathname.equals(pagesArray.get(i).toString())) {
    matchUrl = pagesArray.get(i).toString();
    break;
  }
}
JSONObject rulesObject = jsonObject.optJSONObject("rules");
JSONObject targetObject = rulesObject.optJSONObject(matchUrl);
String navigationBarBackgroundColor = targetObject.optString("navigationBarBackgroundColor");

//获取URL 中的路由进行精准匹配
public String getUrlSubstring(String url) {
  if (url.contains(AnDunServiceGenerator.FORMAL_PATH)) {
    //站内链接
    String baseString = AnDunServiceGenerator.FORMAL_PATH;
    int comIndex = url.indexOf(baseString) + baseString.length();

    if (url.contains("?")) {
      int questionMarkIndex = url.indexOf("?");
      return url.substring(comIndex, questionMarkIndex);
    } else {
      return url.substring(comIndex);
    }
  } else {
    //站外链接 //eg:https://www.huawei.com/cn/?ic_medium=direct&ic_source=surlent
    return "";
  }

}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
HarmonyOS
2024-12-26 14:49:47
浏览
收藏 0
回答 2
回答 2
按赞同
/
按时间
Heiang

参考如下demo,日志过长需要进行分段打印:

import { BusinessError, request } from '@kit.BasicServicesKit';
import fs from '@ohos.file.fs';
import common from '@ohos.app.ability.common';
import buffer from '@ohos.buffer';
import util from '@ohos.util';
import { JSON } from '@kit.ArkTS';

// 获取应用文件路径
let context = getContext(this) as common.UIAbilityContext;
let filesDir = context.filesDir;

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  @State jsonStr: string = '';

  async download() {
    let config: request.agent.Config = {
      action: request.agent.Action.DOWNLOAD,
      url: 'https://app-demo.iandun.com/settings.json?v=1718157761736', // 需要手动将 url 替换为真实服务器的 HTTP 协议地址
      overwrite: true,
      saveas: filesDir + '/jsonStr.text' // 存储地址
    };
    try {
      request.agent.create(context, config).then((task: request.agent.Task) => {
        console.info(`Succeeded in creating a download task. result: ${task.config}`);
        console.info("存储地址:" + filesDir + '/jsonStr.text');
        task.start();
      }).catch((err: BusinessError) => {
        console.error(`Failed to create a download task, Code: ${err.code}, message: ${err.message}`);
      });
    } catch (e) {
      console.log(JSON.stringify(e))
    }
  }

  async readLocalFileWithStream(path: string) {
    try {
      // 存储每次读取的结果
      let buffers: buffer.Buffer[] = [];
      // 打开文件流
      let inputStream = fs.createStreamSync(path, 'r+');
      // 以流的形式读取源文件内容
      let bufSize = 4096;
      let readSize = 0;
      let buf = new ArrayBuffer(bufSize);

      class Option {
        public offset: number = 0;
        public length: number = bufSize;
      }

      let option = new Option();
      option.offset = readSize;
      let readLen = await inputStream.read(buf,
        option);
      // 存储当前读取结果
      buffers.push(buffer.from(buf.slice(0, readLen)))
      readSize += readLen;
      while (readLen > 0) {
        option.offset = readSize;
        readLen = await inputStream.read(buf,
          option);
        // 存储当前读取结果
        buffers.push(buffer.from(buf.slice(0, readLen)))
        readSize += readLen;
      }
      // 关闭文件流
      inputStream.closeSync();

      // 合并内容
      let finalBuf: ArrayBuffer = buffer.concat(buffers).buffer
      console.info(`final ArrayBuffer byteLength is ${finalBuf.byteLength}}`)
      // ArrayBuffer转string
      let textDecoder = util.TextDecoder.create('utf-8');
      let finalUnit = new Uint8Array(finalBuf)
      this.jsonStr = textDecoder.decodeWithStream(finalUnit)
      console.info(`final str Length is ${this.jsonStr.length}}`)
      // 修改打印日志输出大小, IDE控制台日志输出的设置:File->setting->Editor->general->Console下,有个override console cycle buffer size选项
      // 仍然超过需要分段打印
      console.info('final str is ' + this.jsonStr)
    } catch (error) {
      let err = error as BusinessError;
      console.error(`readLocalFileWithStream failed, code is ${err.code},message is ${err.message}`);
    }
  }

  build() {
    Column() {
      Text(this.message)
        .id('DownloadPageHelloWorld')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          this.download()
        })
      Text("获取json")
        .id('DownloadPageHelloWorld')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .onClick(() => {
          this.readLocalFileWithStream(filesDir + '/jsonStr.text')
        })
    }
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
分享
微博
QQ
微信
回复
2024-12-26 16:58:38
wx5b1221fc407ea

​https://ost.51cto.com/answer/38698​​,看看这里试试?

分享
微博
QQ
微信
回复
2025-01-05 09:30:52
相关问题
嵌套JSON字符串解析问题
2419浏览 • 1回复 待解决
如何解析JSON字符串
1668浏览 • 1回复 待解决
HarmonyOS 如何解析json字符串
1173浏览 • 1回复 待解决
关于鸿蒙arkts解析json字符串问题
707浏览 • 1回复 待解决
HarmonyOS 服务端JSON字符串解析问题
897浏览 • 1回复 待解决
如何打印JSON对象和JSON字符串
761浏览 • 1回复 待解决
HarmonyOS url里的字符串怎么解析
250浏览 • 1回复 待解决
Web组件接收超长字符串时会被截断
503浏览 • 1回复 待解决
如何实现Map转JSON字符串
1584浏览 • 1回复 待解决
HarmonyOS 读取本地json文件转成字符串
450浏览 • 1回复 待解决
如何将对象转为JSON字符串
930浏览 • 1回复 待解决
如何将JSON字符串转为Map
661浏览 • 1回复 待解决
怎么动态组装一个json字符串
550浏览 • 1回复 待解决
如何将JSON字符串转Class对象
809浏览 • 1回复 待解决