HarmonyOS ArkTs 解决流式传输编码问题

news2024/11/16 8:04:50

工作日志

日期:2024-11-15

标题:HarmonyOS ArkTs 解决流式传输编码问题

问题描述
  • 问题:在处理流式数据的 HTTP 请求时,服务器返回的数据存在编码问题,导致数据无法正确地解码为字符串。部分数据在解码后出现了乱码,特别是 JSON 格式无法正确解析。
  • 现象:接收到的响应数据在转换为字符串后包含乱码,无法正确转换为 JSON 格式,部分数据内容显示为 \uXXXX 之类的乱码字符。解析 JSON 时抛出异常,提示 “Unexpected token” 等错误信息。
原因分析
  • 原因:问题的根本在于没有正确处理流式传输中的数据拼接和编码转换。原始实现中使用 ArrayBuffer 和手动逐字节转换的方式,这种方式在处理多次接收的数据时比较繁琐,且容易引发编码不匹配的问题。数据在拼接过程中也容易导致一些字符丢失或编码错误。
解决步骤
  1. 使用 Uint8Array 进行数据拼接

    • 设置 Uint8Array 类型用于维护流式响应数据,这样可以方便地将每次接收到的数据进行拼接。
    • 代码如下:
      let resView = new Uint8Array(0);
      httpRequest.on('dataReceive', (data: ArrayBuffer) => {
        const newView = new Uint8Array(resView.length + data.byteLength);
        newView.set(resView, 0);
        newView.set(new Uint8Array(data), resView.length);
        resView = newView;
        console.info('Updated response length: ' + resView.length);
      });
      
  2. 使用 TextDecoder 正确解码 Uint8Array

    • 使用 TextDecoder 来解码 Uint8Array,以便正确地处理 UTF-8 编码的字符,避免手动逐字节转换可能引起的乱码。
    • 代码如下:
      function uint8ArrayToString(buffer: Uint8Array): string {
        const decoder = new util.TextDecoder('utf-8');
        return decoder.decode(buffer);
      }
      
  3. 处理数据结束并转换为字符串或 JSON

    • 在接收到完整数据之后,使用 TextDecoder 解码数据并尝试解析为 JSON。如果解析失败,则进行格式清理(例如将单引号替换为双引号),再尝试解析。
    • 代码如下:
      httpRequest.on('dataEnd', () => {
        console.info('No more data in response, data receive end');
        let resultString = uint8ArrayToString(resView);
        try {
          let jsonData: undefined | string;
          try {
            jsonData = JSON.parse(resultString);
          } catch (error) {
            console.warn("Response could not be parsed as JSON directly.");
            let cleanedString = resultString.replace(/'/g, '"');
            jsonData = JSON.parse(cleanedString);
          }
          console.info('Parsed response as JSON:', JSON.stringify(jsonData));
          callback(JSON.stringify(jsonData));
        } catch (e) {
          console.error('Failed to parse response:', e);
          console.info('Response as raw string:', resultString);
          callback(resultString);
        }
      });
      
  4. 验证问题是否解决

    • 通过多次调用接口并观察日志,确认所有返回数据均能正确解码为 UTF-8 格式,且能正确解析为 JSON。乱码问题彻底解决。
经验教训
  • 总结
    • 在处理流式数据时,正确的编码和拼接方法非常重要。Uint8Array 提供了更高效的方式来拼接和操作二进制数据。
    • 使用 TextDecoder 代替手动字节解析是处理流式数据解码的最佳方式,可以有效避免编码错误和乱码问题。
    • 遇到解析失败的情况时,尝试对数据格式进行清理是个有效的补救措施,尤其在数据格式不完全符合标准时,这种处理方式可以大大提高解析的成功率。
    • 最终解决方案结合了数据的高效拼接和编码转换的正确方法,可以作为今后处理流式传输数据的最佳实践。
      成功接受流式数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2241373.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL数据库最大连接数查询及修改

MySQL数据库最大连接数查询及修改 1. 客户端连接数超出异常案例 Navicat连接异常信息如下: 2. 查看MySQL最大客户端连接数 通过mysql client命令登录MySQL数据库(登录用户不受限制,既可以是 root管理员用户,也可以是常规用户&a…

使用Wireshark获取USB HID(Human Interface Device)报告描述符

使用Wireshark选择需要获取的USB进行抓取数据,找到设备(host)接收信息的数据 第二栏出现hid报告,右击选择复制流 将复制的内容粘贴到USB标准请求及描述符在线分析工具 - USB中文网 进行解析 以图中获取手写板的数据为例&#xff…

TofuAI处理BT1120时序视频要求

时序要求 BT.1120视频用于1920x108030Hz数字视频输入。具体时序必须严格按照说明。BT.1120输入电平为1.8V。 BT1120数字视频采用YCbCr彩色格式输出,串行数据位宽为16bit,亮度在 高8bit,色度在低8bit,亮度和色度在同一个时钟周期输…

聊天服务器(8)用户登录业务

目录 登录状态业务层代码数据模型层代码记录用户的连接信息以及线程安全问题客户端异常退出业务 登录状态 登录且状态变为online 业务层代码 #include "chatservice.hpp" #include "public.hpp" #include <string> #include <muduo/base/Loggi…

通用定时器---输出比较功能

目录 一、概念 二、输出比较的8种模式 三、输出比较输出PWM波形的基本结构 配置步骤 四、示例代码 一、概念 OC&#xff08;OutPut Compare&#xff09;输出比较。输出比较可以通过比较CNT与CCR寄存器的关系&#xff0c;来对输出电平进行置1/置0/翻转的操作&#xff0c;可…

Wireshark中的length栏位

注&#xff1a;Ethernet II的最小data length为46&#xff0c;如果小于&#xff0c;会补全到46. 1.指定网卡抓取的&#xff0c;链路为ethernet。 IPv4 Ethernet II 长度为 14 bytes - L1ipv4 header中的length包括header和payload的总长度 - L2wireshark中length表示抓取的pac…

spring boot整合https协议

整体目录 1. 生成SSL证书 首先&#xff0c;使用keytool生成一个自签名证书。打开命令行工具并运行以下命令&#xff1a; keytool -genkeypair -alias myserver -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 365 这将创建一个名为keystore.jks的文件&#xf…

ceph的集群管理

0 环境说明 ip地址主机名额外硬盘是否加入ceph集群10.0.0.141ceph141sdb 300G&#xff0c;sdc 500G是10.0.0.142ceph142sdb 300G&#xff0c;sdc 500G, sdd 1000G否10.0.0.143ceph143sdb 300G&#xff0c;sdc 500G否 在上一篇文章中&#xff0c;已经成功地初始化了一个ceph管…

C++(Qt)软件调试---内存泄漏分析工具MTuner (25)

C(Qt)软件调试—内存泄漏分析工具MTuner &#xff08;25&#xff09; 文章目录 C(Qt)软件调试---内存泄漏分析工具MTuner &#xff08;25&#xff09;[toc]1、概述&#x1f41c;2、下载MTuner&#x1fab2;3、使用MTuner分析qt程序内存泄漏&#x1f9a7;4、相关地址&#x1f41…

CCI3.0-HQ:用于预训练大型语言模型的高质量大规模中文数据集

摘要 我们介绍了 CCI3.0-HQ&#xff0c;它是中文语料库互联网 3.0&#xff08;CCI3.0&#xff09;的一个高质量500GB子集&#xff0c;采用新颖的两阶段混合过滤管道开发&#xff0c;显著提高了数据质量。为了评估其有效性&#xff0c;我们在不同数据集的100B tokens上从头开始…

LC12:双指针

文章目录 125. 验证回文串 本专栏记录以后刷题碰到的有关双指针的题目。 125. 验证回文串 题目链接&#xff1a;125. 验证回文串 这是一个简单题目&#xff0c;但条件判断自己写的时候写的过于繁杂。后面参考别人写的代码&#xff0c;首先先将字符串s利用s.toLowerCase()将其…

AI 写作(九)实战项目二:智能新闻报道(9/10)

一、项目概述 在当今信息爆炸的时代&#xff0c;新闻传播行业正面临着前所未有的挑战与机遇。随着科技的飞速发展&#xff0c;人们获取信息的渠道日益多样化&#xff0c;对新闻的时效性、准确性和个性化需求也不断提高。在这样的背景下&#xff0c;AI 写作在智能新闻报道中的重…

星际流浪的大模型

种子世界还在太空漫游&#xff0c;航线上捡到一个铁盒子&#xff0c;那是一块硬盘&#xff0c;古老的东西。 长老就安排歌者&#xff0c;你去研究&#xff0c;查查硬盘的来源坐标。 费好大劲&#xff0c;歌者把硬盘中的程序和数据激活&#xff0c;运行了起来。 很有意思&#x…

HarmonyOs DevEco Studio小技巧31--画布组件Canvas

那天我们用画布实现了文字颜色的渐变&#xff0c;实际上画布还有很多好玩的功能&#xff0c;接下来让我们一起试一下画布怎么玩 Canvas 提供画布组件&#xff0c;用于自定义绘制图形。 接口 Canvas Canvas(context?: CanvasRenderingContext2D | DrawingRenderingContext…

C语言.冒泡排序的练习

题目&#xff1a; 1.用C语言编程&#xff0c;用冒泡排序将一个元素个数为20&#xff0c;的一维数组&#xff0c;由大到小的降序。 分析&#xff1a;1.首先创建一个数组&#xff0c;元素个数为20. 2.其次是按降序排列。 3.最后用冒泡排序。 运行代码&#xff1a; #include&l…

RT-DETR融合GhostModel V3及相关改进思路

RT-DETR使用教程&#xff1a; RT-DETR使用教程 RT-DETR改进汇总贴&#xff1a;RT-DETR更新汇总贴 《GhostNetV3: Exploring the Training Strategies for Compact Models》 一、 模块介绍 论文链接&#xff1a;https://arxiv.org/pdf/2404.11202v1 代码链接&#xff1a;https:…

基于yolov8、yolov5的鸟类分类系统(含UI界面、训练好的模型、Python代码、数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下&#xff1a; 算法模型&#xff1a;     yolov8、yolov8 SE注意力机制 或 yolov5、yolov5 SE注意力机制 &#xff0c; 直接提供最少两个训练好的模型。模型十分重要&#xff0c;因为有些同学的电脑没有 GPU&#xff0…

如何保证MySQL与Redis缓存的数据一致性?

文章目录 一、引言二、场景来源三、高并发解决方案1. 先更新缓存&#xff0c;再更新数据库2. 先更新数据库&#xff0c;再更新缓存3. 先删除缓存&#xff0c;再更新数据库4. 先更新数据库&#xff0c;再删除缓存小结 四、拓展方案1. 分布式锁与分布式事务2. 消息队列3. 监听bin…

Chromium 中sqlite数据库操作演示c++

本文主要演示sqlite数据库 增删改查创建数据库以及数据库表的基本操作&#xff0c;仅供学习参考。 一、sqlite数据库操作类封装&#xff1a; sql\database.h sql\database.cc // Copyright 2012 The Chromium Authors // Use of this source code is governed by a BSD-sty…

pycharm分支提交操作

一、Pycharm拉取Git远程仓库代码 1、点击VCS > Get from Version Control 2、输入git的url&#xff0c;选择自己的项目路径 3、点击Clone&#xff0c;就拉取成功了 默认签出分支为main 选择develop签出即可进行开发工作 二、创建分支&#xff08;非必要可以不使用&#xf…