HarmonyOS - DataAbilityHelper访问文件功能

系统 OpenHarmony
Data的提供方和使用方都通过URI(Uniform Resource Identifier,统一资源标识符)来标识一个具体的数据,例如数据库中的某个表或磁盘上的某个文件。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

前言(Data Ability)

使用Data模板的Ability又简称Data,有助于应用管理其自身和其他应用存储数据的访问,并提供与其他应用共享数据的方法。Data既可用于同设备不同应用的数据共享,也支持跨设备不同应用的数据共享。  

数据的存放形式多样,可以是数据库,也可以是磁盘上的文件。Data对外提供对数据的增、删、改、查,以及打开文件等接口,这些接口的具体实现由开发者提供。

URI

Data的提供方和使用方都通过URI(Uniform Resource Identifier,统一资源标识符)来标识一个具体的数据,例如数据库中的某个表或磁盘上的某个文件。HarmonyOS的URI仍基于URI通用标准,格式如下:

 #夏日挑战赛# HarmonyOS - DataAbilityHelper访问文件功能-开源基础软件社区

其中:

  • scheme:协议方案名,固定为“dataability”,代表Data Ability所使用的协议类型。
  • authority:设备ID。如果为跨设备场景,则为目标设备的ID;如果为本地设备场景,则不需要填写。
  • path:资源的路径信息,代表特定资源的位置信息。
  • query:查询参数。
  • fragment:可以用于指示要访问的子资源。

URI示例:

  • 跨设备场景:dataability://device_id/com.domainname.dataability.persondata/person/10
  • 本地设备:dataability:///com.domainname.dataability.persondata/person/10

说明

本地设备的“device_id”字段为空,因此在“dataability:”后面有三个“/”。

访问Data

开发者可以通过DataAbilityHelper类来访问当前应用或其他应用提供的共享数据。DataAbilityHelper作为客户端,与提供方的Data进行通信。Data接收到请求后,执行相应的处理,并返回结果。DataAbilityHelper提供了一系列与Data Ability对应的方法。  

下面介绍DataAbilityHelper具体的使用步骤。

声明使用权限

如果待访问的Data声明了访问需要权限,则访问此Data需要在配置文件中声明需要此权限。

"reqPermissions": [
{
"name": "com.example.dataabilityhelperdemo.DataAbility.DATA"
}
]

如果访问的数据是文件,则还需要添加访问存储读、写的权限:ohos.permission.READ_USER_STORAGE和ohos.permission.WRITE_USER_STORAGE。

创建DataAbilityHelper

DataAbilityHelper为开发者提供了creator()方法(已过期),现在使用create()方法来创建DataAbilityHelper实例。该方法为静态方法,有多个重载。最常见的方法是通过传入一个context对象来创建DataAbilityHelper对象。

获取helper对象示例:

DataAbilityHelper helper = DataAbilityHelper.creator(this);

访问Data Ability

DataAbilityHelper为开发者提供了一系列的接口来访问不同类型的数据(文件、数据库等)。

  • 访问文件
    DataAbilityHelper为开发者提供了FileDescriptor openFile(Uri uri, String mode)方法来操作文件。此方法需要传入两个参数,其中uri用来确定目标资源路径,mode用来指定打开文件的方式,可选方式包含“r”(读), “w”(写), “rw”(读写),“wt”(覆盖写),“wa”(追加写),“rwt”(覆盖写且可读)。

该方法返回一个目标文件的FD(文件描述符),把文件描述符封装成流,开发者就可以对文件流进行自定义处理。

  • 访问数据库
    DataAbilityHelper为开发者提供了增、删、改、查以及批量处理等方法来操作数据库。

创建DataAbility

创建一个名为UserDataAbility的Data

public class UserDataAbility extends Ability {
private static final HiLogLabel LABEL_LOG = new HiLogLabel(3, 0xD001100, "Demo");
@Override
public void onStart(Intent intent) {
super.onStart(intent);
HiLog.info(LABEL_LOG, "UserDataAbility onStart");
}
@Override
public ResultSet query(Uri uri, String[] columns, DataAbilityPredicates predicates) {
return null;
}
@Override
public int insert(Uri uri, ValuesBucket value) {
HiLog.info(LABEL_LOG, "UserDataAbility insert");
return 999;
}
@Override
public int delete(Uri uri, DataAbilityPredicates predicates) {
return 0;
}
@Override
public int update(Uri uri, ValuesBucket value, DataAbilityPredicates predicates) {
return 0;
}
@Override
public FileDescriptor openFile(Uri uri, String mode) {
return null;
}
@Override
public String[] getFileTypes(Uri uri, String mimeTypeFilter) {
return new String[0];
}
@Override
public PacMap call(String method, String arg, PacMap extras) {
return null;
}
@Override
public String getType(Uri uri) {
return null;
}
}

自动生成增删改查、打开文件、获取文件类型、一个回调、获取Uri类型和一个onStart方法。

在config.json配置文件中自动添加了如下配置:

...
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"orientation": "unspecified",
"name": "com.example.dataabilityhelperdemo.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:entry_MainAbility",
"type": "page",
"launchType": "standard"
},
{
"permissions": [
"com.example.dataabilityhelperdemo.DataAbilityShellProvider.PROVIDER"
],
"name": "com.example.dataabilityhelperdemo.UserDataAbility",
"icon": "$media:icon",
"description": "$string:userdataability_description",
"type": "data",
"uri": "dataability://com.example.dataabilityhelperdemo.UserDataAbility"
}
]

如上配置中:

  • type: 类型为data。
  • uri:对外提供的访问路径,唯一。
  • permissions:访问Data Ability时需要申请的访问权限。

关键代码:

//初始化文件
private void initFile() {
//获取文件目录
File dataDir = new File(this.getDataDir().toString());
if(!dataDir.exists()){
dataDir.mkdirs();
}
//目标文件
targetFile = new File(Paths.get(dataDir.toString(),"name.txt").toString());
RawFileEntry rawFileEntry = this.getResourceManager().getRawFileEntry("resources/rawfile/name.txt");
try {
Resource resource = rawFileEntry.openRawFile();
FileOutputStream fos = new FileOutputStream(targetFile);
byte[] buffer = new byte[4096];
int count =0;
while((count = resource.read(buffer)) >=0){
fos.write(buffer,0,count);
}
resource.close();
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}

initFile方法用于初始化文件,将源文件写入目标文件,ResourceManager类的getRawFileEntry方法,获取到RawFileEntry类,RawFileEntry类就代表rawfile目录下的文件,最后通过rawFileEntry.openRawFile()就可以获取到指定文件名的文件。在resource目录的rawfile目录下创建名为name.txt文件,内容如下:

HarmonyOS

效果展示

 #夏日挑战赛# HarmonyOS - DataAbilityHelper访问文件功能-开源基础软件社区

获取文件数据

ability_main.xml布局文件,点击按钮,显示文件里面的内容。

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:alignment="center"
ohos:orientation="vertical">
<Button
ohos:id="$+id:button"
ohos:height="match_content"
ohos:width="match_parent"
ohos:text="获取数据"
ohos:text_size="40vp"/>
<Text
ohos:id="$+id:text_helloworld"
ohos:height="match_content"
ohos:width="match_content"
ohos:background_element="$graphic:background_ability_main"
ohos:layout_alignment="horizontal_center"
ohos:text_size="40vp"
/>

</DirectionalLayout>

关键代码如下:

public class MainAbilitySlice extends AbilitySlice {
private Button button;
private Text textDesc;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
button = (Button)findComponentById(ResourceTable.Id_button);
textDesc = (Text)findComponentById(ResourceTable.Id_text_helloworld);
button.setClickedListener(listener ->this.getFile());
}
private void getFile() {
DataAbilityHelper helper = DataAbilityHelper.creator(this);
Uri uri = Uri.parse("dataability:///com.example.dataabilityhelperdemo.UserDataAbility");
try{
FileDescriptor fileDescriptor = null;
fileDescriptor = helper.openFile(uri,"r");
textDesc.setText(FileUtils.getFileContent(fileDescriptor));
}catch (DataAbilityRemoteException | IOException e){
e.printStackTrace();
}
}
}

FileUtils.java:

public class FileUtils {
public static String getFileContent(FileDescriptor fd)throws IOException{
FileInputStream fis = new FileInputStream(fd);
int a=0;
StringBuilder builder = new StringBuilder();
while ((a= fis.read()) !=-1){
builder.append((char) a);
}
fis.close();
return builder.toString();
}
}

​源码下载地址​

总结

访问文件的关键在于目标文件的文件描述符的获取,使用文件描述符封装成的文件流,进行文件操作。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2022-02-22 08:40:25

微软Windows 11

2010-04-20 13:44:58

Oracle强制访问

2013-08-28 10:56:52

文件选取器

2012-11-01 09:45:50

2018-06-04 15:35:39

修复Windows 10Windows

2010-01-04 09:15:19

Ubuntu Linu

2009-12-23 15:53:36

ADO.NET访问数据

2023-12-21 08:21:01

FileProvid应用程序图片

2023-10-26 07:06:19

前端文件系统

2012-05-03 08:47:35

Windows 7共享

2009-09-15 08:28:42

Windows 7XP模式共享文件

2023-09-12 14:44:12

github前端

2010-01-20 13:42:10

VB.NET访问INIGetPrivateP

2022-03-10 14:45:23

HarmonyAPI操作系统

2010-02-26 14:14:23

Python RSS文

2020-10-09 12:25:42

鸿蒙

2020-11-05 11:38:54

HarmonyOS

2009-12-08 17:00:19

路由器功能

2021-03-24 14:21:20

MacDefender权限

2019-09-16 08:22:12

特权访问管理PAM网络安全
点赞
收藏

51CTO技术栈公众号