HarmonyOS 文件管理fs接口定位定界指导?

如题:HarmonyOS 文件管理fs接口定位定界指导?

阅读 653
1 个回答

文件管理定位指南

本篇文章只介绍ArkTS接口报错问题,调用了@ohos.file.fs下的接口导致报错,且文件管理错误码一般为139开头,确认是文件管理报错请继续按照指导排查。

首先看控制台报错,根据错误码搜索下本文的faq链接,或者根据打断点定位是调用哪个接口报错。

其次根据以下指南排查是否其他子系统的问题:

1、工程resource目录下的资源文件比如rawfile,media为全球化子系统看护,同理resourceManager也是全球化子系统的接口。

2、图库文件,媒体库文件由媒体子系统看护,同理PhotoViewPicker也请走到媒体子系统或图形图像子系统。

3、对于一些系统文件夹/proc,/sys下的读写权限,这些都是由其他子系统自己看护自己文件的读写权限,文件管理不会干涉,且这些文件读写权限都由安全策略管控,需要修改请走安全流程。

4、首选项preferences,数据库等等ohos.data下的接口为分布式子系统看护

文件管理接口问题排查

沙箱文件

fs接口除了open和copy之外只能接受沙箱路径,也就是说fs接口基本只能操作沙箱文件,在调用fs接口时直接传入物理路径一般会报错,正确的方式是通过context获取,获取到context后通过Context.filesDir拿到沙箱路径。

如果不太确定自己沙箱下有什么文件或者路径是否正确,可以进入应用沙箱视角,通过ls查找哪些路径挂载在沙箱下:

ps -ef | grep 应用包名

nsenter -t pid -m sh

fs.openSync()

fs的基本使用参考文件读写

使用open接口可能会发生以下报错:

1390001 Operation not permited

【可能原因】:

1、未进行授权导致读取没有权限,错误码也是13900001,可以排查日志中是否有dec denied。

2、无文件,即应用沙箱目录下执行cd r或rw,抛错No such file or dir,如果文件存在则找文件管理定位。

3、打开图库文件的情况,如果日志查找DataShare,发现媒体库报错失败,返回fd = -1,导致fs.openSync()抛错;

排查是否文件权限问题:使用hdc file send 推送文件到/storage/media/100/local/files/Photo(Picture)目录下,应该通过mediatool的方式推文件到图库。

4、打开media或docs uri时公共目录下不存在对应的文件,走datashare返回-1导致fs.openSync()报错,应用需要排查文件的分享方式是datashare还是bind mount。若未采用datashare则应用排查分享流程:

日志查找:AppFileService或者uri\_permission\_。查看uri对应的路径下有无文件,没有则找系统分享定位。

1390002 No such file or directory

先进入应用沙箱视角,排查沙箱路径下有无指定的文件,如果发现文件存在,则拉文件管理定位。

【可能原因】:

1、入参路径指向不存在的文件且没有CREATE标签,或path参数为空

2、应用沙箱下看不到该目录、文件;

3、带CREATE标签时,文件的父级目录不存在;

4、沙箱目录未成功挂载,应用访问私有沙箱目录失败;

5、自行编辑/拼接/转码uri,可能导致uri格式不正确;

fs.readSync()

使用write接口可能会发生以下报错:

13900005 I/O error

【可能原因】:

1、本地文件可能是文件系统内部错误或文件读写过程中有文件变动

2、跨端场景受网络条件影响

13900008 Bad file descriptor

【可能原因】:

1、可能是在调用fs.read之前没有正确打开文件,或者在读取文件时文件已被关闭。要解决这个问题,可以检查文件是否正确打开,并确保在读取文件时文件没有被关闭。没有以上问题找文件管理定位。

13900010 try again

【可能原因】:

1、当连续read但没有数据可读的情况下,会抛错try again,应用调用readsync则分析代码,代码中不涉及read一般为系统调用,日志搜索readsync找到调用read的模块排查,根据该模块日志标签进行分析,譬如多屏协同场景报错则搜索分布式的报错distributedfile\_daemon:

fs.writeSync()

使用write接口可能会发生以下报错:

13900008 Bad file descriptor

【可能原因】:

1、只读方式打开的文件进行写入操作,检查文件的权限,权限为读写则找文件管理定位。

2、fd指向的不是普通文件,例如:目录;并对其进行写入操作。

3、fd被关闭后,再次使用,检查fd的有效性。由于系统可能会占用0、1、2的文件描述符fd,如果发现CreatewithFd接口创建fd失败或出现错误,先排查fd是否是0-2,否则大于0的fd都是有效的,请找媒体子系统开发处理。

13900020 Invalide argument

【可能原因】:

1、检查编码格式。fs.write只支持utf-8编码格式,其他格式直接读写会报错。需要自己写代码在内存进行编码转换后直接存arraybuffer到文件,参考文件流读写。覆写场景必须要设置OpenMode.TRUNC,默认只是覆盖不会清除。

2、代码入参除了fd和buffer就剩下options,搜索错误码找到报错的代码行,检查options入参。没问题则找文件管理定位。

fs.closeSync()

使用close接口可能发生以下报错:

13900008 Bad file descriptor

【可能原因】:

1、检查fd有效性,fd不代表任何文件或已被关闭后,调用fs.closeSync(fd)会报错。

如果fd有效则找文件管理,如果fd无效,先查找fd的提供者是业务代码还是系统:

确认是业务代码则排查自己子系统fd的生成代码,确认是系统提供则根据日志查找fs.closeSync()是哪个模块调用的

13900020 Invalide argument

【可能原因】:

1、重复调用fs.closeSync(file),搜索下代码里fs.closeSync(file)是否多次调用。

2、入参file变量未定义

搜索file\_api找到报错原因,如果发现文件管理报错入参错误:failed to parse fd or fileEntity from JS parameter,下面日志提示process complete说明文件拷贝没有问题,则一般是代码问题,建议排查使用fs.close的地方是否有使用问题。如果发现文件拷贝也有问题则找文件管理定位。

读写文件可能会有以下报错,全部报错参考链接:文件管理错误码

应用空间统计、缓存清理

当前三方接口statvfs.getFreeSize可以获取的是data分区的存储空间,不包括system等系统路径分区的大小。

getContext(this).cacheDir只返回系统的默认缓存路径/data/storage/el2/base/haps/entry/cache,而一般应用缓存可能存储在以下几个目录:

/data/storage/el1/base/cache

/data/storage/el1/base/haps/entry/cache

/data/storage/el2/base/cache

/data/storage/el2/base/haps/entry/cache

出现清理cacheDir目录但缓存大小没什么变化,可以检查其余几个目录是否有缓存没有清理,仍有问题按以下方式排查:

统计缓存大小的接口storageStatistics.getCurrentBundleStats()本身是透传调用包管理的GetBundleStats接口,有问题该找包管理;

统计逻辑是计算应用内所有文件夹名称为cache的目录大小,发现有少许缓存没有清空的情况也请看看应用自己创建的cache文件夹里是否有文件残留,仍有问题找文件管理开发处理。