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

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

3天内不再提示

自制一款鸿蒙应用文件管理器

OpenHarmony技术社区 来源:OST开源开发者 2023-03-08 14:22 次阅读

在涉及应用内部存储的开发时,常常翻阅手机自带的文件管理检查。正好在学习文件管理的接口,想着实现一个第三方组件用于当前应用的文件查看和管理。

介绍

如下:

类型:第三方组件.ets

语言框架:ArkTs

API 版本:HarmonyOS SDK 8

模型: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模块
这里给大家整理了基本的接口:

116cdbba-b9cf-11ed-bfe3-dac502259ad0.png

11858b6a-b9cf-11ed-bfe3-dac502259ad0.png

下面是底层开放访问的三大目录:

11a56d04-b9cf-11ed-bfe3-dac502259ad0.png

以上接口返回的路径都是以/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.md
API 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

效果图

上下浏览:

11c91470-b9cf-11ed-bfe3-dac502259ad0.gif

删除操作:

11fa47d4-b9cf-11ed-bfe3-dac502259ad0.gif

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

    关注

    33

    文章

    7629

    浏览量

    148432
  • API
    API
    +关注

    关注

    2

    文章

    1379

    浏览量

    60983
  • 文件管理器
    +关注

    关注

    0

    文章

    16

    浏览量

    3013
  • 鸿蒙
    +关注

    关注

    55

    文章

    1597

    浏览量

    42115
  • HarmonyOS
    +关注

    关注

    79

    文章

    1796

    浏览量

    29250

原文标题:自制一款鸿蒙应用文件管理器

文章出处:【微信号:gh_834c4b3d87fe,微信公众号:OpenHarmony技术社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    为Linux高级用户提供的强大的文件管理器

    想要为系统提供高度可定制的文件管理器?nnn 就是一个功能强大但轻量级的文件管理器,可在 Linux 终端内工作。
    发表于 11-14 11:19 1184次阅读

    如何自制一款功能固定的红外遥控

    如题现有自带红外遥控的家庭影院音响套,想应用在酒店场景中,即插卡上电以后,音响自动打开并播放。由于音响本身上电以后保持待机状态,必须要通过遥控开关或者主机开关按钮才能是开机状态。因此想自制
    发表于 01-10 15:51

    请问如何自制一款功能固定的红外遥控

    现有自带红外遥控的家庭影院音响套,想应用在酒店场景中,即插卡上电以后,音响自动打开并播放。由于音响本身上电以后保持待机状态,必须要通过遥控开关或者主机开关按钮才能是开机状态。因此想自制一款
    发表于 01-10 16:09

    关于自制一款简易遥控开关

    自制一款简易遥控,只控制开关即可,敢问哪位大神有详细的电路原理图
    发表于 02-15 16:30

    请问如何自制一款无刷电机控制

    如何自制一款无刷电机控制
    发表于 03-16 10:25

    USB电源管理器LTC40851电子资料

    概述:LTC4085-1是一款专为便携式电池供电型应用而设计的 USB 电源管理器和锂离子电池充电器。该器件控制被 USB 外设用于操作和电池充电的总电流。
    发表于 04-08 06:31

    USB电源管理器LTC4066电子资料

    概述:LTC4066是一款USB 电源管理器和锂离子电池充电器,专为在便携式电池供电型应用中工作而设计。这些器件可控制被 USB 外设用于操作和电池充电的总电流。
    发表于 04-09 06:19

    USB电源管理器LTC40661电子资料

    改善:LTC4066-1是一款USB 电源管理器和锂离子电池充电器,专为在便携式电池供电型应用中工作而设计。这些器件可控制被 USB 外设用于操作和电池充电的总电流。
    发表于 04-12 06:26

    如何自制一款光耦检测电路

    如何自制一款光耦检测电路
    发表于 05-25 07:57

    sdk5鸿蒙利用文件管理器获取文件Uri的过程

    )); } 捕捉(异常e){系统。出.println(e.toString()); }}} }}文件最大可以选择500个,它返回的uri好像是安卓的uri,所以需要转换成鸿蒙的,这样子就到了看路径的形式,他应该是把文件弄到了
    发表于 04-27 11:03

    USB烧录和应用文件

    USB烧录和应用文件
    发表于 03-02 18:01 196次下载

    re管理器删除系统软件操作方法

    RE管理器一款高权限文件管理器,获取Root权限后对系统文件进行操作,可以新建文件夹,查看编辑
    发表于 12-20 11:44 1.2w次阅读
    re<b class='flag-5'>管理器</b>删除系统软件操作方法

    re管理器进入编辑文件方法

    Root Explorer,R.E管理器用户量巨大,装机必备!安卓最佳文件管理器,没有之一!RE管理器原生简体中文,支持新建文件夹,多种格式
    发表于 12-20 13:47 4423次阅读
    re<b class='flag-5'>管理器</b>进入编辑<b class='flag-5'>文件</b>方法

    什么是re文件管理器_re管理器有什么用

    Android用户很多人遇到想找到手机系统文件却找不到的情况,RE管理器就是一款手机Root后能够获得高级权限,查看手机系统文件,蓝牙文件
    发表于 12-20 14:29 1.7w次阅读

    如何在文件管理器中隐藏文件文件

    如果一个系统被多个用户使用,你或许出于个人原因想在文件管理器中隐藏一些文件文件夹不让其他人看到(绝大多数用户不会对 Linux 系统进行深入了解,所以他们只会看到
    发表于 05-13 09:34 1190次阅读
    如何在<b class='flag-5'>文件</b><b class='flag-5'>管理器</b>中隐藏<b class='flag-5'>文件</b>和<b class='flag-5'>文件</b>夹