為你推薦一款高效的IO元件——okio
前不久,三方元件庫上新了一批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資訊,將其新增到輸出流緩衝區的雙向連結串列的尾部,省去一次資料複製過程。
圖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的資料寫入輸出流緩衝區。
圖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=
步驟三: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:檔案寫入和讀取
本示例通過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解碼
本示例通過ByteString實現Base64解碼功能,程式碼如下:
let byteStringObj = new okio.ByteString.ByteString(''); //生成ByteString物件let decodeBase64 = byteStringObj.decodeBase64('SGVsbG8gd29ybGQ='); //解碼Base64字串this.decodeBase64Value = JSON.stringify(decodeBase64); //顯示解碼結果
示例3:十六進位制解碼
本示例通過ByteString實現十六進位制解碼功能,程式碼如下:
let byteStringObj = new okio.ByteString.ByteString('');let decodehex = byteStringObj.decodeHex('48656C6C6F20776F726C640D0A');this.decodeHexValue = JSON.stringify(decodehex);
示例4:Utf8編碼
本示例通過ByteString實現Utf8編碼功能,程式碼如下:
let byteStringObj = new okio.ByteString.ByteString('');let encodeUtf8 = byteStringObj.encodeUtf8('Hello world #4 ❤ ( ͡ㆆ ͜ʖ ͡ㆆ)');this.encodeUtf8Value = JSON.stringify(encodeUtf8);
本期okio元件就為大家介紹到這裡了。okio元件已開源,歡迎大家參與貢獻。
開源地址如下:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70009402/viewspace-2899845/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 為 PHP 轉 Go 的朋友們推薦一款神器PHPGo
- 推薦一款讓你縱橫Github的讀碼神器Github
- OKio – 重新定義了“短小精悍”的IO框架框架
- 推薦一款VNC軟體,推薦一款超級好用的VNC軟體!VNC
- 推薦一款專為新手用的Python開發工具Python
- 推薦Chrome外掛,讓你高效使用瀏覽器Chrome瀏覽器
- 開源推薦:一款輕量級、高效能的電商系統
- 為CRM選型推薦一款靠譜的CRM系統
- 推薦一款好用的CRM軟體?
- 【推薦】最高效的Python爬蟲框架!Python爬蟲框架
- 為什麼IDEA不推薦你使用@Autowired ?Idea
- 推薦一款超好用的編輯器
- 推薦一款 MySQL 命令列神器MySql命令列
- 推薦 vue2、vue3 中功能最強大的表格元件,效能最強大的表格元件推薦、可編輯表格推薦Vue元件
- 為什麼主流APP的推薦總能符合你口味?推薦系統瞭解一下APP
- 10 個 Flutter 元件推薦 - 2Flutter元件
- 你的站點抗壓麼?推薦一款超方便的開源壓測工具
- 推薦一款好用的Macos應用Radial MenuMac
- 推薦幾款常用的企業網盤軟體,你喜歡哪一款?
- 推薦五款免費的開源軟體,總有一款適合你
- 想要一款簡單高效的Mac日記應用?Day One for Mac軟體推薦給大家!Mac
- 推薦幾款高效的Python文字編輯器!Python
- 高效且開源的網路安全工具推薦!
- 為什麼我推薦你使用 systemd timer 替代 cronjob?
- 推薦一款 Python 微服務框架 - NamekoPython微服務框架
- 推薦一款線上共享雲桌面
- WPF優秀元件推薦之MahApps元件APP
- 譯 10 個 Flutter 元件推薦 – 4Flutter元件
- 譯 10 個 Flutter 元件推薦 – 5Flutter元件
- WPF優秀元件推薦之FreeSpire元件
- 只推薦一本 JavaScript 書,你推薦哪本?JavaScript
- 推薦一款好用的程式碼視覺化工具視覺化
- 推薦一款漂亮的 Java 圖形驗證碼Java
- 推薦幾款專案管理工具 總有一款適合你專案管理
- 5大電腦軟體推薦!每一款都是精心挑選,良心推薦!
- 推薦5個我常用的軟體,簡單高效
- 推薦6個高效的語言處理Python庫Python
- 推薦一款 Flutter Push 推送功能外掛Flutter