鸿蒙开发实例|分布式文件服务

简介: 鸿蒙开发实例|分布式文件服务

Harmony OS应用数据管理不仅支持单设备的各种结构化数据的持久化,还支持跨设备之间数据的同步、共享及搜索功能,因此,开发者基于Harmony OS应用数据管理功能,能实现应用程序数据在不同终端设备之间的无缝衔接,从而保证用户在跨设备使用数据时所用数据的一致性。

在正式讲解HarmonyOS中的分布式文件服务之前,先简单介绍一下相关概念。


01、分布式文件系统(Distributed File System,DFS)


通过计算机网络将分布在不同地点的节点相连,利用网络进行节点间的通信和数据传输,从而将固定于某个地点的某个文件系统,扩展到任意多个地点/文件系统,众多的节点组成的文件系统网络即为分布式系统。简单来讲,DFS为分布在网络上任意位置的资源提供一个逻辑上的树形文件系统结构,从而使用户访问分布在网络上的共享文件更加简便。分布式文件系统的突出优点就是可以屏蔽文件系统的物理位置,人们在使用分布式文件系统时,无须关心数据是存储在哪个节点上或者是从哪个节点获取的,而只需像使用本地文件系统一样管理和存储文件系统中的数据。


此外,分布式文件系统还包括以下特点:

冗余性: 分布式文件系统可以提供冗余备份,当系统中某些节点出错时,整体文件服务不会停止,还能继续为用户提供服务,具有较高的容错性。

安全性: 分布式文件系统的安全性离不开其冗余性,当出现故障的节点存储的数据损坏时可以由其他节点进行数据恢复。此外,在分布式文件系统中,大量数据被分散到不同的节点上进行存储,数据丢失的风险大大减小。

扩展性: 分布式文件系统可以通过网络连接将大量的计算机连接到一起,任何计算机只需经过简单的配置就可以加入分布式文件系统中。


02、分布式文件


分布式文件是指依赖于分布式文件系统并分散存储在多个用户设备上的文件,应用间的分布式文件目录互相隔离,不同应用的文件不能互相访问。


03、文件元数据


文件元数据是用于描述文件特征的数据,包含文件名、文件大小、创建、访问、修改时间等信息。


在HarmonyOS中,分布式文件服务支持用户设备中的应用程序在同一账号下多设备之间进行文件共享。即应用程序可以屏蔽文件具体的存储位置,在多个设备之间无障碍访问文件。HarmonyOS中分布式文件服务的运作机制如图1所示。

image.png

■ 图1 Harmony OS中分布式文件服务的运作机制


从图1可以看出,在HarmonyOS中,分布式文件服务采用无中心节点的设计,每个设备都存储一份全量的文件元数据和本设备上产生的分布式文件,元数据在多台设备间互相同步,当应用需要访问分布式文件时,分布式文件服务首先查询本设备上的文件元数据,获取文件所在的存储设备,然后对存储设备上的分布式文件服务发起文件访问请求,将文件内容读取到本地。


实际上,在HarmonyOS中实现分布式文件服务前,需要满足以下条件:

(1) 应用程序如需使用分布式文件服务完整功能,需要申请分布式数据管理权限,具体地,申请ohos.permission.DISTRIBUTED_DATASYNC权限,从而允许不同设备间的数据交换。

(2) 要实现分布式共享文件,则多个设备需登录同一个华为账号,打开蓝牙设备,连接同一个WLAN 局域网。

(3) 存在多设备并写的场景,为了避免冲突,开发者需要对文件加锁保护,保证文件独享。非持锁情况下,并发写冲突时,后一次会覆盖前一次。

(4) 应用访问分布式文件时,文件所在设备不能离线,否则文件不能访问。

(5) 当网络情况较差时,访问存储在远端的分布式文件可能会长时间得不到响应甚至响应失败,因此需要应用考虑到对这种场景的处理。

(6) 当两台设备有同名文件时,如果元数据进行同步则会产生冲突,分布式文件服务会根据时间戳将文件按创建的先后顺序重命名,因此,为避免此类场景出现,应用在文件名上可以进行相应设备区分,例如,deviceID+时间戳。


下面通过一个实例学习如何在HarmonyOS中具体实现多设备间的文件共享。实例实现了在两个手机设备上进行分布式时间读写的功能,即在手机A 上单击写入Button,将当前时间写入分布式文档。在手机B上单击读取Button,可以从分布式文档中获取手机A 中写入的时间,反之亦然。需要注意的是,两个手机设备需要登录同一个华为账号,故需要开启多设备协同权限。


首先,创建Phone设备下的Java模板新项目,打开项目目录下的MainAbilitySclice.java文件,在onStart()方法中声明布局,代码如下:


DirectionalLayout directionLayout= new DirectionalLayout(this);
directionLayout.setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT);
directionLayout.setHeight(ComponentContainer.LayoutConfig.MATCH_PARENT);
directionLayout.setOrientation(Component.VERTICAL);
directionLayout.setPadding(32, 32, 32, 32);

在布局中添加Text组件用以显示提示信息及读取到的时间,代码如下:


Text text= new Text(this);
text.setText("初始文本"); //设置初始显示文本
text.setTextSize(50);
DirectionalLayout.LayoutConfig layoutConfig = newDirectionalLayout.LayoutConfig (ComponentContainer.LayoutConfig.MATCH_CONTENT,ComponentContainer.LayoutConfig.MATCH_CONTENT);
layoutConfig.alignment = LayoutAlignment.HORIZONTAL_CENTER;
text.setLayoutConfig(layoutConfig);
directionLayout.addComponent(text);

在本例中两个设备通过各自的Button组件实现时间的读写,因此,需要添加两个Button组件,首先添加写入时间的Button组件,代码如下:


//实现写入功能的Button,用来读取当前时间,并写入分布式文档中
Button button1 = new Button(this);
layoutConfig.setMargins(0, 50,0,0);
button1.setLayoutConfig(layoutConfig);
button1.setText("写入现在时间");
button1.setTextSize(50);
ShapeElement background1 = new ShapeElement();
background1.setRgbColor(new RgbColor(0xFF51A8DD));
background1.setCornerRadius(25);
button1.setBackground(background1);
button1.setPadding(10, 10, 10, 10);
button1.setClickedListener(new Component.ClickedListener() {
      @Override
      public void onClick(Component Component) {
           goWrite(text); //单击Button,实现写入功能
      }
});
directionLayout.addComponent(button1);


添加读取时间的Button组件,代码如下:


//实现读取功能的Button,从分布式文档中读取已经写入的时间
Button button2 = new Button(this);
layoutConfig.setMargins(0, 50,0,0);
button2.setLayoutConfig(layoutConfig);
button2.setText("读取上一个时间");
button2.setTextSize(50);
ShapeElement background2 = new ShapeElement();
background2.setRgbColor(new RgbColor(0xFF5100DD));
background2.setCornerRadius(25);
button2.setBackground(background1);
button2.setPadding(10, 10, 10, 10);
button2.setClickedListener(new Component.ClickedListener() {
      @Override
//单击Button,实现读取功能
      public void onClick(Component Component) {
           goRead(text);
      }
});
directionLayout.addComponent(button2);


写入功能是由goWrite()方法实现的,分析其实现过程,代码如下:


//goWrite():写入button1的onClick事件执行的方法
private void goWrite(Text text) {
     String sharedFileName = sharedFileName(this); //获取分布式文件路径
     SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
     String str=simpleDateFormat.format(new Date().getTime()); //获取时间戳并转换成标准形式
//将时间写入分布式文件
     try{
          FileWriter fileWriter = new FileWriter(sharedFileName,false);
          fileWriter.write(str);
          fileWriter.close();
     } catch (IOException e) {
            e.printStackTrace();
     }
     text.setText("写入的时间:"+str); text.invalidate();
}

读取功能是由goRead()方法实现的,其实现过程代码如下:


//goRead():读取button2的onClick事件执行的方法
private void goRead(Text text) {
     String sharedFileName = sharedFileName(this); //获取分布式文件路径
  //读取分布式文件中的数据,若读到则输出,若没读到则输出没读到
     try{
            FileReader fileReader = new FileReader(sharedFileName);
            BufferedReader br = new BufferedReader(fileReader);
            String b = br.readLine();
            text.setText("读取到的上一个写入的时间:"+b);
            text.invalidate();
            fileReader.close();
        } catch (IOException e) {
            e.printStackTrace();
            text.setText("没读到");
            text.invalidate();
        }
}


二者都是通过shareFileName()方法获取分布式文件路径的,代码如下:


File distDir = context.getDistributedDir(); //获取分布式文件目录
     //在分布式文件目录下新建一个名为note.txt的文件,读写都在这个文件中进行
     String filePath = distDir+File.separator+"note.txt";
     return filePath; //返回新建文件的路径
}

需要说明的是,利用Context.getDistributedDir()接口可以获取属于自己的分布式目录,然后通过libc或JDK 接口,可以在该目录下创建、删除、读写文件或目录。本例中在所获取的分布式目录下创建了一个读写文件note.txt。


基于两个手机设备进行验证,在开始功能验证之前,两个手机需要登录同一个华为账号,并且需要开启多设备协同权限且开启多设备协同连接。具体的设置过程可参考前面对多设备协同权限设置的介绍。


设置完成后进行功能验证。首先,在未写入的情况下直接进行读取,读取结果如图2所示,未写入的情况下读取内容为空。

image.png

■ 图2 未写入情况下直接进行读取


由Phone A 写入当前时间,Phone B读取当前时间,读写效果如图3所示。

image.png


■ 图3 Phone A写入当前时间,Phone B读取A写入的时间


由Phone B 写入当前时间,Phone A 进行读取时,读写效果如图4 所示。

image.png

■ 图4 Phone B写入当前时间,Phone A读取B写入的时间


至此,分布式文件服务功能成功实现。


目录
相关文章
|
21天前
|
JavaScript 安全 前端开发
【HarmonyOS开发】ArkTS基础语法及使用(鸿蒙开发基础教程)
【HarmonyOS开发】ArkTS基础语法及使用(鸿蒙开发基础教程)
264 4
|
21天前
|
存储 数据安全/隐私保护
鸿蒙开发:自定义一个动态输入框
在鸿蒙开发中,如何实现这一效果呢,最重要的解决两个问题,第一个问题是,如何在上一个输入框输入完之后,焦点切换至下一个输入框中,第二个问题是,如何禁止已经输入的输入框的焦点,两个问题解决完之后,其他的就很是简单了。
45 13
鸿蒙开发:自定义一个动态输入框
|
24天前
|
小程序 测试技术 API
鸿蒙原生开发手记:03-元服务开发全流程(开发元服务,只需要看这一篇文章)
本文详细介绍元服务的开发及上架全流程,涵盖元服务的特点、创建项目、服务卡片、签名打包、开发测试及上架审核等环节,帮助开发者轻松掌握从零开始开发并发布元服务的全过程。元服务以其轻量、免安装、易于使用等特点,成为未来服务提供的重要形式。
60 13
鸿蒙原生开发手记:03-元服务开发全流程(开发元服务,只需要看这一篇文章)
|
29天前
|
Android开发
鸿蒙开发:自定义一个简单的标题栏
本身就是一个很简单的标题栏组件,没有什么过多的技术含量,有一点需要注意,当使用沉浸式的时候,注意标题栏的位置,需要避让状态栏。
鸿蒙开发:自定义一个简单的标题栏
|
29天前
|
API
鸿蒙开发:切换至基于rcp的网络请求
本文的内容主要是把之前基于http封装的库,修改为当前的Remote Communication Kit(远场通信服务),无非就是通信的方式变了,其他都大差不差。
鸿蒙开发:切换至基于rcp的网络请求
|
26天前
|
传感器 数据处理 数据库
鸿蒙开发Hvigor插件动态生成代码
【11月更文挑战第13天】Hvigor 是鸿蒙开发中的构建系统插件,主要负责项目的构建、打包及依赖管理,并能根据预定义规则动态生成代码,如数据库访问、网络请求等,提高开发效率和代码一致性。适用于大型项目初始化和组件化开发。
|
24天前
|
Android开发 索引
鸿蒙开发:自定义一个车牌省份简称键盘
鸿蒙搞起来就比较的简单,直接一个Grid组件便可以搞定,最后的删除按钮,使用布局选项GridLayoutOptions便可轻松实现。
鸿蒙开发:自定义一个车牌省份简称键盘
|
26天前
|
安全 UED 开发者
鸿蒙开发:沉浸式效果实现
沉浸式效果实现后,一定要注意安全区域的内容避让,防止内容延伸后被导航条或者状态栏遮挡,具体是选择安全区域或者窗口管理方式,按照需求进行处理,如果仅仅是某个页面,直接安全区域即可。
鸿蒙开发:沉浸式效果实现
|
1月前
|
UED
鸿蒙next版开发:相机开发-适配不同折叠状态的摄像头变更(ArkTS)
在HarmonyOS 5.0中,ArkTS提供了强大的相机开发能力,特别是针对折叠屏设备的摄像头适配。本文详细介绍了如何在ArkTS中检测和适配不同折叠状态下的摄像头变更,确保相机应用在不同设备状态下的稳定性和用户体验。通过代码示例展示了具体的实现步骤。
67 8
|
1月前
|
API 内存技术
鸿蒙next版开发:相机开发-拍照(ArkTS)
在HarmonyOS 5.0中,ArkTS提供了一套完整的API来管理相机功能,特别是拍照功能。本文详细介绍如何在ArkTS中实现拍照功能,包括导入接口、创建会话、配置会话、触发拍照及监听拍照输出流状态,并提供代码示例进行详细解读。通过本文,你将掌握如何在HarmonyOS 5.0中使用ArkTS实现高效的拍照功能。
79 7