0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一个可应用于HarmonyOS的高效IO库

HarmonyOS开发者 来源:HarmonyOS开发者 作者:HarmonyOS开发者 2022-06-08 09:22 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

前不久,三方组件库上新了一批JS/eTS组件,其中就包括okio组件。okio是一个可应用于HarmonyOS的高效IO库,它依托于系统能力,提供字符串的编解码转换能力,基础数据类型的读写能力以及对文件读写的支持。本期将为大家介绍okio的工作原理及使用方法。

一、okio的产生背景

IO,即输入输出(Input/Output)。绝大多数应用都需要与外部进行数据交互,这就会涉及IO。系统提供了IO能力,在使用系统IO时,通常需要一个中间缓冲区来保存读取到的数据。数据先从输入流缓冲区复制到中间缓冲区,再从中间缓冲区复制到输出流缓冲区。中间多次拷贝,降低了IO效率,同时增加了系统消耗。为了满足开发者对IO的更高要求,三方组件库推出IO处理利器——okio(JS版本)。okio使用Segment作为数据存储容器,通过提供Segment移动、共享、合并和分割的能力,让数据读写变得非常灵活,也减少了数据复制,提升了IO效率。此外,okio还通过SegmentPool对Segment进行回收和复用,减少大量创建Segment带来的系统消耗。下面就带大家深入了解JS版本的okio的工作原理,探索它是如何提升IO效率的~

二、两个基本概念

在深入解析okio的工作原理之前,我们先来了解两个基本概念:Segment和SegmentPool。

1. Segment

okio将数据分割成一块块的片段存放在Segment里面。Segment是一个数据存储的真正类,内部维护着一个大小为8192字节的字节数组用于存储数据。Segment最小可共享、可写入的数据大小为1024字节。Segment使用pos、limit、shared、owner、prev、next来分别记录读写位置、是否可写入、是否能共享、数据拥有者、前置节点和后置节点信息。Segment对外提供sharedCopy、unsharedCopy、split、push、pop、compact、writeTo等接口用于操作数据。

Segment同时拥有前置节点和后置节点,构成一个双向链表。读取数据的时候,从双向链表的头部开始读取;而写入数据的时候,从双向链表的尾部写入数据。

2. SegmentPool为了管理Segment,okio维护了一个Segment对象池(即SegmentPool),对废弃的Segment回收、复用和内存共享,从而减少内存的申请和GC(garbage collection,垃圾收集)的频率,使性能得到优化。SegmentPool是一个由最多8个Segment组成的单链表。一个Segment的最大大小是8192字节(即8KB),所以SegmentPool的最大大小是64KB。

三、okio的工作原理

okio组件最重要的功能就是“读”和“写”。下面我们就从读写开始,了解okio的工作原理。

1. 读写数据okio读写数据的过程中,遵循大块数据移动、小块数据复制的原则。okio从输入流读取数据到输入流缓冲区时,会先找到双向链表尾部的Segment节点,如果此节点的剩余容量足够,则直接将读取到的数据存入到此节点。如果此节点的剩余容量不足,则从SegmentPool里面取一个Segment链接到双向链表的尾部,然后将数据存入这个新节点。okio从输入流缓冲区读取数据,再写入数据到输出流缓冲区。这个过程比较复杂,有以下几种情况:

(1) 从输入流缓冲区获取到Segment,如果数据是满的(字节数组data长度为8092字节),那么直接修改此Segment的prev和next信息,将其添加到输出流缓冲区的双向链表的尾部,省去一次数据复制过程。

bc533964-e6c8-11ec-ba43-dac502259ad0.png

图1大块数据移动 (2) 从输入流缓冲区获取到Segment(假设为Segment1),如果数据不是满的,可以通过pos和limit信息来确定segment1的可读数据,再和输出流缓冲区的双向链表的尾部节点(假设为Segment2)的剩余容量进行对比: 如果Segment1的可读数据比Segment2的剩余容量小,则把Segment1的数据复制到Segment2,然后回收Segment1到SegmentPool。 如果Segment1的可读数据比Segment2的剩余容量大,那么直接修改Segment1的prev和next信息,将其添加到Segment2的后面。

(3) 从输入流缓冲区获取到Segment(假设为Segment3),如果只需要传递部分数据(比如总数据为4096字节,只传递1024字节),okio会通过split接口将Segment3拆分成含3072字节数据的Segment3-1和含1024字节数据的Segment3-2,然后按照(2)的逻辑将Segment3-2的数据写入输出流缓冲区。

bc708a3c-e6c8-11ec-ba43-dac502259ad0.png

图2 Segment拆分

拆分Segment的时候,可以通过参数指定拆分后的第一个Segment含有的未读字节数(byteCount)。拆分后,第一个Segment包含的数据范围是[pos,pos+byteCount),第二个Segment包含的数据范围是[pos+byteCount,limit)。拆分Segment时也遵循大块数据移动、小块数据复制的原则。当byteCount大于1024时,使用共享的Segment,否则复制数据。(注:文件、流、socket相关的IO优化需要系统支持,待后续版本优化提供。)2. Segment的回收与复用接下来,我们再来看看SegmentPool是如何回收和复用Segment的。

每次okio想要使用Segment就从SegmentPool中获取,使用完毕后又会放回到SegmentPool中等待复用,核心方法为take()和recycle()。

(1) take()方法

take()方法负责从对象池单链表的头部获取可以使用的Segment。如果获取不到,说明单链表是空的,此时新创建一个Segment给缓冲区使用。如果能获取到,则取出单链表的头部节点,再将下一个节点置为单链表的头部节点,并将取出来的Segment的next置空,同时更新对象池大小。

(2) recycle()方法recycle()方法负责回收缓冲区里面使用完毕的Segment。回收开始时,首先更新对象池大小,然后把回收对象Segment添加到单链表头部,接着重置Segment的pos和limit为0。注意,以下情况不会回收Segment:
  • 当前Segment的prev和next不为空

  • 当前Segment是共享的

  • 对象池已经有8个Segment了

3. 字符串处理除了Segment和SegmentPool外,okio还封装了ByteString类来进行字符串处理。ByteString提供Base64编解码、utf-8编码、十六进制编解码、大小写转换、内容比较等丰富的API,可以很方便地处理字符串。在进行字符串处理时,由于ByteString同时持有原始字符串和对应的字节数组,可以直接使用字节数组里面的数据进行操作,不需要先将字符串转换为字节数组。特别是在频繁转换编码的场景下,通过这种以空间换时间的方式,可以避免字符串与字节数组的多次转换,减少了时间和系统性能消耗。

四、okio的使用及示例

1. 前置配置步骤一:在entry 的package.json文件中添加以下依赖项。
"dependencies": {    "okio": "^1.0.0"  }
步骤二:配置仓库镜像地址。
npm config set @ohos:registry=https://repo.harmonyos.com/npm/
步骤三:DevEco Studio的Terminal里面输入以下命令下载源代码。
cd entrynpm install @ohos/okio

步骤四:文件的头部引入okio库。
 import okio from '@ohos/okio';
步骤五:在config.json文件中申请存储权限。
   "reqPermissions": [      {        "name": "ohos.permission.WRITE_USER_STORAGE", //写入用户存储的权限        "reason": "Storage",        "usedScene": {          "when": "always",          "ability": [            "com.example.okioapplication.MainAbility"          ]        }      },      {        "name": "ohos.permission.READ_USER_STORAGE", //读取用户存储的权限        "reason": "Storage",        "usedScene": {          "when": "always",          "ability": [            "com.example.okioapplication.MainAbility"          ]        }      },      {        "name": "ohos.permission.WRITE_EXTERNAL_MEDIA_MEMORY", //写入外部存储的权限        "reason": "Storage",        "usedScene": {          "when": "always",          "ability": [            "com.example.okioapplication.MainAbility"          ]        }      }    ]    }

2. 代码实现执行完上面的配置操作后,就可以进入代码编写阶段了。开发者可以使用okio提供的丰富的API接口来实现功能。下面为大家展示四个实现示例,供大家参考学习。

示例1:文件写入和读取

bc977156-e6c8-11ec-ba43-dac502259ad0.gif

本示例通过sink将内容写入文件,通过source从文件读取内容。代码如下:
//通过sink将内容写入文件var sink = new okio.Sink(this.fileUri);sink.write(this.Value,false); //通过source从文件读取内容var source = new okio.Source(this.fileUri);source.read().then(function (data) { context.readValue = data;    }).catch(function (error) {console.log("error=>"+error);    });

示例2:Base64解码

bce3cdb2-e6c8-11ec-ba43-dac502259ad0.gif

本示例通过ByteString实现Base64解码功能,代码如下:
let byteStringObj = new okio.ByteString.ByteString(''); //生成ByteString对象let decodeBase64 = byteStringObj.decodeBase64('SGVsbG8gd29ybGQ='); //解码Base64字符串this.decodeBase64Value = JSON.stringify(decodeBase64); //显示解码结果
示例3:十六进制解码

bd4c4dce-e6c8-11ec-ba43-dac502259ad0.gif

本示例通过ByteString实现十六进制解码功能,代码如下:
let byteStringObj = new okio.ByteString.ByteString('');let decodehex = byteStringObj.decodeHex('48656C6C6F20776F726C640D0A');this.decodeHexValue = JSON.stringify(decodehex);
示例4:Utf8编码

bd746d04-e6c8-11ec-ba43-dac502259ad0.gif

本示例通过ByteString实现Utf8编码功能,代码如下:
let byteStringObj = new okio.ByteString.ByteString('');let encodeUtf8 = byteStringObj.encodeUtf8('Hello world #4  ( ͡ㆆ ͜ʖ ͡ㆆ)');this.encodeUtf8Value = JSON.stringify(encodeUtf8);

本期okio组件就为大家介绍到这里了。okio组件已开源,欢迎大家参与贡献。

开源地址如下:

https://gitee.com/openharmony-tpc/okio还想了解更多优秀的组件?欢迎点击下方的“阅读原文”,跳转到三方组件库,更多优秀组件等你来发现!

审核编辑 :李倩


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 组件
    +关注

    关注

    1

    文章

    600

    浏览量

    19065
  • HarmonyOS
    +关注

    关注

    80

    文章

    2157

    浏览量

    36280

原文标题:为你推荐一款高效的IO组件——okio

文章出处:【微信号:HarmonyOS_Dev,微信公众号:HarmonyOS开发者】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    华大九天Liberal IO精准K解决方案介绍

    便捷性提出了更高要求。华大九天Liberal IO自动化K解决方案,以全类型IO覆盖、高精度建模与简便易上手为核心优势,为芯片设计企业提供专业的IO特征化提取保障,助力
    的头像 发表于 04-13 16:11 172次阅读
    华大九天Liberal <b class='flag-5'>IO</b>精准K<b class='flag-5'>库</b>解决方案介绍

    分享CW32 IO拓展项目:使用CW32L010做GPIO/ADC 扩展

    置的GPIO口 以及 四通用定时器 。 正是基于这些特性,该芯片非常适合用于两类核心应用场景: 功能简单的独立设备 ,如传感器节点、小家电主控等。 作为主控系统的扩展单元 ,尤其是IO扩展和模拟信号采集。 当
    的头像 发表于 03-31 21:43 139次阅读
    分享<b class='flag-5'>一</b><b class='flag-5'>个</b>CW32 <b class='flag-5'>IO</b>拓展项目:使用CW32L010做GPIO/ADC 扩展

    专门用于复杂环境的机器视觉照明——激光器

    51camera的激光器可应用于隧道补光、路面检测补光、轨道检测、钢板检测等
    的头像 发表于 03-24 17:58 141次阅读
    专门<b class='flag-5'>用于</b>复杂环境的机器视觉照明——激光器

    广和通携手高通推出可应用于无人智能控制场景的模组及解决方案

    衡量无人控制移动终端成熟度的核心指标和生命线。广和通基于高通X85的5G-A平台,推出可应用于无人智能控制场景的模组及解决方案,为具身机器人、无人机、无人出租车(Robotaxi)及 AGV 提供了集高速率、双链路并发、安全冗余与实时感知于体的通信方案。
    的头像 发表于 03-24 10:36 1977次阅读

    菲诺克科技推出沁恒CH9347有线透传芯片应用于移动电源新国标方案

    菲诺克科技推出沁恒CH9347有线透传芯片应用于移动电源新国标方案 菲诺克科技根据新国标移动电源与各类终端便捷通信的核心需求,采用沁恒USB透传芯片CH9347推出了充电宝USB通信、低功耗蓝牙
    发表于 02-10 09:10

    恒讯科技解析:如何安装MySQL并创建数据

    管理系统(RDBMS),使用结构化查询语言(SQL)高效地组织和管理数据。它是全球最受欢迎的开源数据系统之,广泛应用于网页开发、电子商务和商业应用。 常见用例  MySQL 是多种
    的头像 发表于 01-14 14:25 331次阅读

    钉钉正式开源HarmonyOS图片编辑组件

    近日,由钉钉团队自主研发的“HarmonyOS图片编辑组件”正式上线OpenHarmony三方中心仓并开源。作为款填补鸿蒙社区图像处理领域空白的重量级组件,该方案基于HarmonyOS
    的头像 发表于 01-05 09:58 652次阅读

    圣邦微电子发布高效率LED驱动芯片SGM37601

    圣邦微电子推出SGM37601,款六通道40V高效率LED驱动芯片。该器件可应用于平板电脑和笔记本电脑等中尺寸LCD显示屏设备。
    的头像 发表于 12-12 17:20 3258次阅读
    圣邦微电子发布<b class='flag-5'>高效</b>率LED驱动芯片SGM37601

    超实用!页搞定威纶通IO显示

    IO监控画面是自动化设备中用于快速诊断故障的常用功能。然而,当设备IO点数量众多时,往往需要配置多个监控画面,这过程不仅繁琐易错,也降低了排查效率。 那么,能否在
    的头像 发表于 11-12 15:42 876次阅读
    超实用!<b class='flag-5'>一</b>页搞定威纶通<b class='flag-5'>IO</b>显示

    GraniStudio:IO写入例程

    说明 实现输出IO控制以及读取。 2.1通过初始化IO算子连接格拉尼控制器IO块,导入工程自动进行连接。 2.2 通过IO配置算子输出配置的IO
    的头像 发表于 08-22 16:47 868次阅读
    GraniStudio:<b class='flag-5'>IO</b>写入例程

    Aisler 发布 Lovely Library:为 KiCad 打造的高质量欧洲元器件

    “  看到 Aisler 的推文,觉得挺搞笑的,原来元器件也可以有地域之分; 不过对用户来说,更多的高质量器件定会让设计更高效。好东西还是要分享!  ”   以上的内容翻译如下:
    的头像 发表于 08-04 11:13 1021次阅读
    Aisler 发布 Lovely Library:<b class='flag-5'>一</b><b class='flag-5'>个</b>为 KiCad 打造的高质量欧洲元器件<b class='flag-5'>库</b>

    模块通吃DI/DO/AI/AO!无线IO的万能信号采集方案

    无线IO通讯模块是种特殊的输入输出(I/O)设备,它采用无线通讯技术实现I/O信号的传输。以下是对无线IO通讯模块的详细介绍: 、定义与功能 定义:无线
    的头像 发表于 07-22 10:15 731次阅读
    <b class='flag-5'>一</b><b class='flag-5'>个</b>模块通吃DI/DO/AI/AO!无线<b class='flag-5'>IO</b>的万能信号采集方案

    文详解Advanced IO wizard异步模式

    7nm Versal系列相对于16nm Ultrascale plus系列,IO做了升级,U+系列的HPIO在Versal升级为XPIO。Versal系列每一个XPIO bank包含54IO
    的头像 发表于 07-11 09:52 1772次阅读
    <b class='flag-5'>一</b>文详解Advanced <b class='flag-5'>IO</b> wizard异步模式

    HarmonyOS入门指南

    上手的HarmonyOS工具,借助众多实用工具类,致力于助力开发者迅速构建鸿蒙应用。 2、开源框架 harmony-utils 款功能丰富且极易上手的HarmonyOS工具
    的头像 发表于 06-27 00:11 916次阅读

    HarmonyOS5云服务技术分享--云数据使用指南

    ​​: 敏感数据启用字段级加密(如用户手机号)。 ? ​​总结​​ 华为云数据(CloudDB)让HarmonyOS应用的数据管理变得轻松又高效!通过本文的代码示例和技巧,相信你已经掌握了增删改查
    发表于 05-22 18:29