在涉及應(yīng)用內(nèi)部存儲(chǔ)的開(kāi)發(fā)時(shí),常常翻閱手機(jī)自帶的文件管理檢查。正好在學(xué)習(xí)文件管理的接口,想著實(shí)現(xiàn)一個(gè)第三方組件用于當(dāng)前應(yīng)用的文件查看和管理。
介紹
如下:
類型:第三方組件.ets
語(yǔ)言框架:ArkTs
模型:FA
目前已實(shí)現(xiàn)的功能:
上下級(jí)文件的瀏覽
查看文件基本信息(名稱、大小、修改日期)
刪除文件
文件路徑顯示
組件寬高、橫豎屏自適應(yīng)
使用示例
代碼如下:
//導(dǎo)入組件 import{Filer}from'../views/filemanager'; //調(diào)用組件 structIndex{ ... Column(){ Filer() //Filer({Width:'100%',Height:'100%'})//可傳入寬高參數(shù) }.width('100%').height('100%') }
接下來(lái)是實(shí)現(xiàn)思路的簡(jiǎn)單分析,有興趣的可以看一下源代碼。
實(shí)現(xiàn)思路
主要涉及兩個(gè)方面:
接口函數(shù)
交互設(shè)計(jì)(后續(xù)出)
①接口函數(shù)
接口方法整理:接口函數(shù)涉及到文件目錄的訪問(wèn)、文件信息的讀取、文件的刪除等,文檔接口非常多,但只需認(rèn)識(shí)基本的幾個(gè)接口就夠用了。
文檔傳送門(mén):@ohos.fileio (文件管理)-文件管理-接口參考(ArkTS及JS API)-手機(jī)、平板、智慧屏和智能穿戴開(kāi)發(fā)-ArkTS API參考-HarmonyOS應(yīng)用開(kāi)發(fā)
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模塊這里給大家整理了基本的接口:
下面是底層開(kāi)放訪問(wèn)的三大目錄:
以上接口返回的路徑都是以/data/user/0/包名/ 開(kāi)頭,是多種訪問(wèn)路徑的其中一種。
PS:Stage模型中提供的目錄訪問(wèn)接口與 FA 不同,有三個(gè)目錄:tempDir、cacheDir、filesDir,還有其它類型的目錄如數(shù)據(jù)庫(kù)目錄等。
具體參考 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';
②代碼思路
以數(shù)據(jù)結(jié)構(gòu)中最基本的樹(shù)狀結(jié)構(gòu)數(shù)組來(lái)保存文件的父子關(guān)系和個(gè)體信息,每一次的文件操作相當(dāng)于維護(hù)這樣的一個(gè)文件樹(shù)。
每一個(gè)文件對(duì)應(yīng)一個(gè) node 結(jié)點(diǎn):
typenode={ id:number,//當(dāng)前編號(hào) fileName:string,//文件名稱 fileType:FileType,//文件類型 path:string,//完整有效訪問(wèn)路徑 parentId:number,//父級(jí)編號(hào) size:number,//文件大小 mTime:number//修改時(shí)間 } enumFileType{ 'dir'=0,//文件夾 'file'=1,//普通文件 'else'=2//其它類型文件 }主要變量:
//---文件樹(shù)相關(guān)變量 privaterelativePath:string=''//內(nèi)部存儲(chǔ)器上此應(yīng)用程序的文件目錄 privateabsolutePath:string=''//根目錄 privatecachePath:string=''//內(nèi)部存儲(chǔ)目錄 privatehistoryNodesTree:Array維護(hù)文件樹(shù)方法:=[]//保存所有文件信息,即文件樹(shù),需要維護(hù) privaterootNodes:Array =[]//保存三大目錄根的信息,不可繼續(xù)往上訪問(wèn) //---與UI相關(guān)的變量 @StateprivatecurNodes:Array =[]//展示當(dāng)前層級(jí)所有文件 @StateprivatepathArray:Array =['']//路徑分割數(shù)組,用于組件頂部路徑展示 @State@Watch('onCurParentNodeChange')curParentNode:node=undefined//保存上一級(jí)結(jié)點(diǎn),方便結(jié)點(diǎn)和路徑更新 privateWidth:Length='100%'//組件默認(rèn)寬 privateHeight:Length='100%'//組件默認(rèn)高
backToDir()//返回上一級(jí) deleteSelectedDir()//刪除操作 unlink()//刪除文件 rmdir()//刪除目錄 openSelectedDir()//打開(kāi)目錄,進(jìn)入下一級(jí) addNewNode()//添加新結(jié)點(diǎn) getOrCreateLocalDir()//獲取應(yīng)用根目錄 getFilesDir()//獲取file://根目錄 getCacheDir()//獲取cache://根目錄工具方法:
handleFileSize()//文件字節(jié)格式轉(zhuǎn)換 fileSizeTransform()//文件字節(jié)格式轉(zhuǎn)換 timestampToDate()//時(shí)間戳與常用時(shí)間格式轉(zhuǎn)換下面是部分與 fileio 密切相關(guān)的函數(shù): 打開(kāi)選中目錄:
openSelectedDir(parentNode:node):void{//傳參:待打開(kāi)的目錄結(jié)點(diǎn) this.curParentNode=parentNode//更新保存當(dāng)前結(jié)點(diǎn)的父結(jié)點(diǎn) fileIo.opendir(parentNode.path).then(dir=>{//打開(kāi)文件夾 letdirect=dir.readSync()//讀取下一個(gè)子文件 this.curNodes.length=0//刷新UI while(direct!==undefined){//找出所有子文件,逐個(gè)構(gòu)造node結(jié)點(diǎn) this.addNewNode(parentNode,direct) direct=dir.readSync() } dir.closeSync()//關(guān)閉目錄 }).catch(()=>{}) }
添加新文件結(jié)點(diǎn):
addNewNode(parentNode:node,direct?:fileIo.Dirent):void{//構(gòu)造node結(jié)點(diǎn)并維護(hù)文件樹(shù) if(!direct){//入?yún)⒅剌d 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()){//普通文件外的文件類型不展示字節(jié)大小 size=fileStat.size } letnewNode:node={//構(gòu)造node結(jié)點(diǎn) 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)//更新當(dāng)前UI this.historyNodesTree.push(newNode)//維護(hù)文件樹(shù) 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:當(dāng)目錄存在子文件時(shí),不允許直接調(diào)用 rmdir() 刪除該目錄,需要先刪除所有子文件、子目錄,否則會(huì)報(bào)錯(cuò) code:39,這里我采用深度搜索遍歷的方法刪除所有子文件、子目錄。
錯(cuò)誤碼參考鏈接(這是 3.1 beta 的文檔,終于可以清晰地知道錯(cuò)誤碼的信息了。)
https://developer.harmonyos.com/cn/docs/documentation/doc-references-V3/errorcode-filemanagement-0000001427585212-V3?catalogVersion=V3
效果圖
上下瀏覽:
刪除操作:
-
接口
+關(guān)注
關(guān)注
33文章
8526瀏覽量
150861 -
API
+關(guān)注
關(guān)注
2文章
1487瀏覽量
61829 -
文件管理器
+關(guān)注
關(guān)注
0文章
16瀏覽量
3125 -
鴻蒙
+關(guān)注
關(guān)注
57文章
2321瀏覽量
42749 -
HarmonyOS
+關(guān)注
關(guān)注
79文章
1967瀏覽量
30033
原文標(biāo)題:自制一款鴻蒙應(yīng)用文件管理器
文章出處:【微信號(hào):gh_834c4b3d87fe,微信公眾號(hào):OpenHarmony技術(shù)社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論