HarmonyOS鸿蒙Next中this.context.resourceManager.getRawFileContentSync后面的路径怎么写?

HarmonyOS鸿蒙Next中this.context.resourceManager.getRawFileContentSync后面的路径怎么写? 错误提示是Invalid relative path和SourceMap is not initialized yet ,不知道是不是路径写错了,还是什么问题?

8 回复

【背景知识】

[@ohos.resourceManager (资源管理)](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-resource-manager)提供资源获取能力。根据当前的Configuration配置,获取最匹配的应用资源或系统资源。resourceManager.getRawFileContentSync获取resources/rawfile目录下对应的rawfile文件内容,使用同步形式返回。

rawfile支持创建多层子目录,子目录名称可以自定义,文件夹内可以自由放置各类资源文件。目录中的资源文件会被直接打包进应用,不经过编译,也不会分配资源ID。通过指定文件路径和文件名访问。

Invalid relative path:根据参数相对路径, 找不到对应的资源。

【问题分析】

使用resourceManager.getRawFileContentSync获取resources/rawfile目录下对应的rawfile文件内容,且出现Invalid relative path报错,说明读rawfile目录下的文件出错。可能原因有:getRawFileContentSync参数路径填写错误或者rawfile目录下面的文件类型分析错误。

【解决方案】

对于rawfile目录下面的文件一般分为两类:

  • 资源文件(例如string、color、plural等json文件,通过$rawfile访问,返回Resource类型对象,适用于界面控件绑定资源文件情形等,通常不涉及写操作):需要注意的是,和其他资源目录下不同的是,需要通过指定文件路径和文件名来访问。
    • 单Hap/hsp包内访问:通过"$rawfile(‘filename’)“形式访问,其中,filename为rawfile目录下文件的相对路径,文件名需要包含后缀,路径开头不可以”/"开头。格式示例如下:

图片

Image($rawfile('media/background.png'))
  • 跨Hap/Hsp访问:(由于har包是随模块编译的,直接对应的模块中引用即可,不涉及跨包访问,这里不再赘述。)需要先在entry中oh-package.json5中添加moudle依赖;使用格式为 $rawfile(’[hsp].filename’) ,其中[hsp]为hsp模块名,filename仍为rawfile目录下文件的相对路径。格式示例如下:
$rawfile('[hsp].oneFile/twoFile/icon.png')

其他类型文件(例如,db文件、txt文件等等,原始文件形式保存):需要用到资源管理模块resourceManager的常见接口:

getRawFileContentSync getRawFd
功能 用户获取resources/rawfile目录下对应的rawfile文件内容 用户获取resources/rawfile目录下rawfile文件所在hap的descriptor信息
常见适用场景 处理文件内容小的文件,直接将rawfile目录下的文件的二进制buffer读取到内存中进行读写 处理文件内容大的文件,需要获取rawfile目录下的文件的fd,将rawfile目录下的文件拷贝到应用沙箱下,再对沙箱文件进行读写
  • 文件内容小的文件,进行访问(以文本文件,举例说明):
@Entry
@Component
struct Page {
  build() {
    Column() {
      Button("读取文件").onClick(()=>{
        // 获取文件内容
        // 确保在工程目录src/main/resources/rawfile里存在a.pdf文档
        let content: Uint8Array = this.context.resourceManager.getRawFileContentSync('a.pdf');
      })
    }
  }
}
  • 文件内容大的文件,进行访问(以数据库db文件,举例说明):
    1. 先通过getRawFd获取rawfile目录下的文件描述符fd;
    2. 然后,在应用沙箱里创建对应的沙箱文件,获取到对应的文件描述符fd;
    3. 将rawfile目录下的文件通过buffer的方式拷贝到沙箱文件下;
    4. 最后,在应用沙箱下访问对应文件。 详细代码请查看代码示例

【常见FAQ】

Q:官网对于getRawFd接口官网API说明是访问Hap包目录的下的文件(getContext().resourceManager.getRawFd(‘rawfilepath’)可获取Rawfile所在hap包的descriptor信息),那么如何在entry下获取hsp的rawfile资源? A:本知识其实已经提到了,对于跨hap/hsp的模块需要createModuleContext接口,先获取对应模块的context,再使用该context调用getRawFdSync获取文件句柄。

import { UIAbility, application, common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index {
  build() {
    Row() {
      Column() {
        Button("hello")
          .onClick(async () => {
            let moduleContext: common.Context;
            let context = getContext(this) as common.Context
            application.createModuleContext(context, 'library').then((data: Context) => {
              moduleContext = data;
              let fd = moduleContext.resourceManager.getRawFdSync('startIcon.png')
            }).catch((error: BusinessError) => {
              let code: number = (error as BusinessError).code;
              let message: string = (error as BusinessError).message;
              console.error(`createModuleContext failed, error.code: ${code}, error.message: ${message}`);
            })
        })
      }
    }
  }
}

更多FAQ请查看如何读写rawfile目录下的文件

更多关于HarmonyOS鸿蒙Next中this.context.resourceManager.getRawFileContentSync后面的路径怎么写?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


文件必须存储在 src/main/resources/rawfile/ 目录下或自定义资源目录的对应位置,调用时只需填写相对于rawfile的子路。不能包含/rawfile/前缀或盘符路径。

另外检查一下hvigorconfig.ts中路径配置:

includeNode({

  name: "module",

  path: "./src", // 使用相对路径

  scope: ["debug","release"]

})

代码示例:

// 获取当前模块上下文
const context = getContext(this) as common.UIAbilityContext
// 获取跨模块上下文(比如目标模块名为"library")
const libContext = context.createModuleContext('library')

// 读取本模块资源
try {
  const localData = context.resourceManager.getRawFileContentSync('local.json')
} catch (error) {
  console.error(`读取本模块资源失败: ${JSON.stringify(error)}`)
}

// 读取其他模块资源
try {
  const libData = libContext.resourceManager.getRawFileContentSync('lib_res.json')
} catch (error) {
  console.error(`读取跨模块资源失败: ${JSON.stringify(error)}`)
}

这两个错误分别对应文件路径配置错误项目构建 / 调试配置问题,需针对性排查。

import { BusinessError } from '@kit.BasicServicesKit';

try {
  this.context.resourceManager.getRawFileContent("test.txt", (error: BusinessError, value: Uint8Array) => {
    if (error != null) {
      console.error("error is " + error);
    } else {
      let rawFile = value;
    }
  });
} catch (error) {
  let code = (error as BusinessError).code;
  let message = (error as BusinessError).message;
  console.error(`callback getRawFileContent failed, error code: ${code}, message: ${message}.`);
}

这个代码 this.context.resourceManager.getRawFileContent 这里默认是 entry 文件下的路径,

如果你的模块是其他的 的模块,得这样写

this.context.createModuleContext("xxx").resourceManager.getRawFileContent("你文件的名字+后缀")

getRawFileContentSync要求的路径格式为相对于rawfile目录的相对路径。

文件直接放在resources/rawfile下

如果你的模块是hsp 的模块 获取 resourceManager 不能这么直接访问.

对于跨hap/hsp的模块需要createModuleContext接口,先获取对应模块的context,再使用该context调用getRawFdSync获取文件句柄

参考以下连接: 中常见问题部分.

https://developer.huawei.com/consumer/cn/doc/architecture-guides/tools-v1_2-ts_43-0000002346637729

我之前碰到过hsp读取 resourceManager 接口提示, Invalid relative path, 是因为在hsp 模块使用本地的resourceManager 接口要使用createModuleContext 获得context.

你的文件需要再 rawfile 目录下:

以入口模块为例: xxx/entry/src/main/resources/rawfile/test.json

this.context.resourceManager.getRawFileContentSync("test.json")

在HarmonyOS鸿蒙Next中,this.context.resourceManager.getRawFileContentSync的路径参数应使用rawfile目录下的相对路径。例如,若文件位于resources/rawfile/data/example.txt,则路径参数应为'data/example.txt'。路径字符串需使用单引号或双引号括起来,且无需包含rawfile目录名。

在HarmonyOS Next中,getRawFileContentSync的路径应使用相对路径,格式为entry/src/main/resources/rawfile/下的文件路径。例如,若文件位于rawfile/data.json,则路径应写为data.json

错误提示Invalid relative path通常表示路径格式不正确或文件不存在。请检查路径是否拼写准确,且文件已放置在正确的目录下。SourceMap is not initialized yet可能与开发环境相关,建议重启IDE或清理项目缓存。

确认文件路径和开发环境状态后,问题通常可以解决。

回到顶部