在涉及應用內部存儲的開發時,常常翻閱手機自帶的文件管理檢查。正好在學習文件管理的接口,想著實現一個第三方組件用于當前應用的文件查看和管理。
介紹
如下:
類型:第三方組件.ets
語言框架:ArkTs
模型:FA
目前已實現的功能:
上下級文件的瀏覽
查看文件基本信息(名稱、大小、修改日期)
刪除文件
文件路徑顯示
組件寬高、橫豎屏自適應
使用示例
代碼如下:
//導入組件 import{Filer}from'../views/filemanager'; //調用組件 structIndex{ ... Column(){ Filer() //Filer({Width:'100%',Height:'100%'})//可傳入寬高參數 }.width('100%').height('100%') }
接下來是實現思路的簡單分析,有興趣的可以看一下源代碼。
實現思路
主要涉及兩個方面:
接口函數
交互設計(后續出)
①接口函數
接口方法整理:接口函數涉及到文件目錄的訪問、文件信息的讀取、文件的刪除等,文檔接口非常多,但只需認識基本的幾個接口就夠用了。
文檔傳送門:@ohos.fileio (文件管理)-文件管理-接口參考(ArkTS及JS API)-手機、平板、智慧屏和智能穿戴開發-ArkTS API參考-HarmonyOS應用開發
https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-apis-fileio-0000001333640945#ZH-CN_TOPIC_0000001333640945__%E5%AF%BC%E5%85%A5%E6%A8%A1%E5%9D%97
importfileiofrom'@ohos.fileio'; importfeatureAbilityfrom'@ohos.ability.featureAbility'; letcontext=featureAbility.getContext();//FA模型獲取Context模塊 //letcontext=globalThis.abilityContext;//Stage模型獲取Context模塊這里給大家整理了基本的接口:
下面是底層開放訪問的三大目錄:
以上接口返回的路徑都是以/data/user/0/包名/ 開頭,是多種訪問路徑的其中一種。
PS:Stage模型中提供的目錄訪問接口與 FA 不同,有三個目錄:tempDir、cacheDir、filesDir,還有其它類型的目錄如數據庫目錄等。
具體參考 gitee 文檔 Context 模塊:
https://gitee.com/openharmony/docs/blob/8504866055592da2a92a539ab0074c93642d6aa1/zh-cn/application-dev/reference/apis/js-apis-inner-application-context.mdAPI 9 還提供了新的文件管理接口,但是接口方法大同小異:
importfsfrom'@ohos.file.fs';
②代碼思路
以數據結構中最基本的樹狀結構數組來保存文件的父子關系和個體信息,每一次的文件操作相當于維護這樣的一個文件樹。
每一個文件對應一個 node 結點:
typenode={ id:number,//當前編號 fileName:string,//文件名稱 fileType:FileType,//文件類型 path:string,//完整有效訪問路徑 parentId:number,//父級編號 size:number,//文件大小 mTime:number//修改時間 } enumFileType{ 'dir'=0,//文件夾 'file'=1,//普通文件 'else'=2//其它類型文件 }主要變量:
//---文件樹相關變量 privaterelativePath:string=''//內部存儲器上此應用程序的文件目錄 privateabsolutePath:string=''//根目錄 privatecachePath:string=''//內部存儲目錄 privatehistoryNodesTree:Array維護文件樹方法:=[]//保存所有文件信息,即文件樹,需要維護 privaterootNodes:Array =[]//保存三大目錄根的信息,不可繼續往上訪問 //---與UI相關的變量 @StateprivatecurNodes:Array =[]//展示當前層級所有文件 @StateprivatepathArray:Array =['']//路徑分割數組,用于組件頂部路徑展示 @State@Watch('onCurParentNodeChange')curParentNode:node=undefined//保存上一級結點,方便結點和路徑更新 privateWidth:Length='100%'//組件默認寬 privateHeight:Length='100%'//組件默認高
backToDir()//返回上一級 deleteSelectedDir()//刪除操作 unlink()//刪除文件 rmdir()//刪除目錄 openSelectedDir()//打開目錄,進入下一級 addNewNode()//添加新結點 getOrCreateLocalDir()//獲取應用根目錄 getFilesDir()//獲取file://根目錄 getCacheDir()//獲取cache://根目錄工具方法:
handleFileSize()//文件字節格式轉換 fileSizeTransform()//文件字節格式轉換 timestampToDate()//時間戳與常用時間格式轉換下面是部分與 fileio 密切相關的函數: 打開選中目錄:
openSelectedDir(parentNode:node):void{//傳參:待打開的目錄結點 this.curParentNode=parentNode//更新保存當前結點的父結點 fileIo.opendir(parentNode.path).then(dir=>{//打開文件夾 letdirect=dir.readSync()//讀取下一個子文件 this.curNodes.length=0//刷新UI while(direct!==undefined){//找出所有子文件,逐個構造node結點 this.addNewNode(parentNode,direct) direct=dir.readSync() } dir.closeSync()//關閉目錄 }).catch(()=>{}) }
添加新文件結點:
addNewNode(parentNode:node,direct?:fileIo.Dirent):void{//構造node結點并維護文件樹 if(!direct){//入參重載 this.curNodes.push(parentNode) this.historyNodesTree.push(parentNode) return } letpath=parentNode.path+'/'+direct.name letfileType=direct.isDirectory()//是否為文件夾類型 letsize:number=-1 letfileStat=fileIo.statSync(path)//獲取文件具體信息 if(!fileType&&fileStat.isFile()){//普通文件外的文件類型不展示字節大小 size=fileStat.size } letnewNode:node={//構造node結點 path:path, fileName:direct.name, fileType:fileType?0:direct.isFile()?1:2, parentId:parentNode.id, id:(this.historyNodesTree.length+1), size:size, mTime:fileStat.mtime } this.curNodes.push(newNode)//更新當前UI this.historyNodesTree.push(newNode)//維護文件樹 console.info('fsj---addNewNode:'+newNode.fileName) }
刪除目錄(包含刪除文件操作):
asyncrmdir(node:node){ letpath=node.path awaitthis.bfsRmdir(path)//刪除所有子文件、子目錄后 fileIo.rmdir(node.path).then(()=>{//再刪除該目錄 showToast('刪除成功') this.curNodes=this.curNodes.filter(item=>item.id!=node.id) }).catch((err)=>{ showToast('刪除失敗:'+JSON.stringify(err)) }) } asyncbfsRmdir(path:string):Promise{//深度搜索遍歷,刪除該目錄下的所有子文件、子目錄 returnnewPromise((res)=>{ fileIo.opendir(path).then(async(dir)=>{ letdirect=dir.readSync() while(direct!==undefined){ letsonPath=path+'/'+direct.name if(fileIo.statSync(sonPath).isDirectory()){ awaitthis.bfsRmdir(sonPath) } fileIo.unlinkSync(sonPath) direct=dir.readSync() } dir.closeSync() res() }) }) }
PS:當目錄存在子文件時,不允許直接調用 rmdir() 刪除該目錄,需要先刪除所有子文件、子目錄,否則會報錯 code:39,這里我采用深度搜索遍歷的方法刪除所有子文件、子目錄。
錯誤碼參考鏈接(這是 3.1 beta 的文檔,終于可以清晰地知道錯誤碼的信息了。)
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/errorcode-filemanagement-0000001427585212-V3?catalogVersion=V3
效果圖
上下瀏覽:
刪除操作:
-
接口
+關注
關注
33文章
8691瀏覽量
151919 -
API
+關注
關注
2文章
1511瀏覽量
62396 -
文件管理器
+關注
關注
0文章
17瀏覽量
3171 -
鴻蒙
+關注
關注
57文章
2392瀏覽量
43052 -
HarmonyOS
+關注
關注
79文章
1982瀏覽量
30577
原文標題:自制一款鴻蒙應用文件管理器
文章出處:【微信號:gh_834c4b3d87fe,微信公眾號:OpenHarmony技術社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論