标签 全场景智能生态 下的文章

目录

  • 前言
  • 关于跨设备文件访问和拷贝
  • 实现跨设备文件访问
  • 实现跨设备文件拷贝
  • 结束语

    前言

    在HarmonyOS构建的全场景智能生态体系中,“万物互联”不再是抽象的概念,而是通过一系列核心技术落地到用户日常操作中的实用体验,其中跨设备文件访问与拷贝功能,更是衔接多终端、提升用户操作效率的关键支撑,也是鸿蒙原生应用开发中不可或缺的核心技能模块。随着鸿蒙原生生态的持续完善,越来越多的开发者开始聚焦多设备协同场景的应用开发,而跨设备文件操作能力,直接决定了应用在全场景生态中的适配性与竞争力,它能够让用户在手机、平板、智慧屏、手表等不同鸿蒙设备之间,无缝共享、传输各类文件,无需依赖第三方传输工具,也无需进行复杂的设备配对与设置,真正实现“一次操作,多端同步”的便捷体验。为了帮助广大鸿蒙原生开发者快速掌握这一核心技术,规避开发误区,本文将以实战为导向,在保留可直接复用示例代码的基础上,详细拆解跨设备文件访问与拷贝的实现逻辑、技术选型、操作步骤,从理论解析到实操落地,全方位讲解如何在HarmonyOS应用中高效实现这两项关键功能,助力开发者轻松适配全场景协同开发需求。

image.png

关于跨设备文件访问和拷贝

HarmonyOS搭载的分布式技术体系,为跨设备文件访问与拷贝功能的实现提供了坚实的底层支撑,其中分布式文件系统与分布式任务调度两大核心能力,共同打破了不同设备之间的文件壁垒,让应用能够像操作本地文件一样,轻松访问和操控远程设备上的文件资源,大幅降低了跨设备开发的难度。
先为大家解析跨设备文件访问功能,分布式文件系统为鸿蒙应用提供了原生的跨设备文件访问能力,当开发者在两台不同的设备上安装了同一应用后,通过系统提供的基础文件接口,即可跨设备读写另一台设备上该应用分布式文件路径(/data/storage/el2/distributedfiles/)下的所有文件。典型的应用场景就是多设备数据流转,当两台设备完成组网互联后,设备A上的目标应用,能够直接访问设备B上同一应用分布式路径下存储的文件;如果开发者希望应用中的某个文件能够被其他设备访问,只需将该文件移动至上述分布式文件路径即可,操作便捷且无需额外配置。
然后再来讲解跨设备文件拷贝功能,同样基于分布式文件系统的支撑,鸿蒙应用具备了跨设备、跨应用的文件拷贝能力,开发者可通过系统基础文件接口,实现不同设备、不同应用之间的文件拷贝操作。以多设备数据流转场景为例,当两台设备完成组网互联后,设备A上的应用在执行复制操作时,会先将自身沙箱文件拷贝至设备A的分布式文件路径中;而设备B在执行粘贴操作时,则会从自身的分布式文件路径中,将对应的文件拷贝至目标沙箱路径下,整个过程由系统底层自动完成设备间的协同,开发者无需关注底层通信细节。

实现跨设备文件访问

1、完成分布式组网

首先需将需要实现跨设备访问的两台设备,登录同一鸿蒙账号完成身份认证,同时确保两台设备的蓝牙与Wi-Fi功能处于开启状态(无需手动完成蓝牙互连,Wi-Fi也无需接入同一局域网,系统会自动完成设备组网匹配)。

2、访问跨设备文件

同一应用在不同设备之间实现跨设备文件访问,核心操作是将需要共享的文件放置在应用沙箱的分布式文件路径下,下面先展示设备A在分布式路径下创建测试文件并写入内容的具体操作,具体的示例代码如下所示:

import { fileIo as fs } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';

let context = getContext(this) as common.UIAbilityContext; // 获取设备A的UIAbilityContext信息
let pathDir: string = context.distributedFilesDir;
// 获取分布式目录的文件路径
let filePath: string = pathDir + '/test.txt';

try {
  // 在分布式目录下创建文件
  let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  // 向文件中写入内容
  fs.writeSync(file.fd, 'content');
  // 关闭文件
  fs.closeSync(file.fd);
} catch (error) {
  let err: BusinessError = error as BusinessError;

} 

设备B需主动向设备A发起链路建立,待建链成功后,即可在自身的分布式文件路径下读取设备A创建的测试文件。需要特别说明的是,此处需通过分布式设备管理接口获取设备A的networkId,以此实现设备间的精准关联,具体示例代码如下所示:

import { fileIo as fs } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { buffer } from '@kit.ArkTS';
import { distributedDeviceManager } from '@kit.DistributedServiceKit'

// 通过分布式设备管理的接口获取设备A的networkId信息
let dmInstance = distributedDeviceManager.createDeviceManager("com.example.hap");
let deviceInfoList: Array<distributedDeviceManager.DeviceBasicInfo> = dmInstance.getAvailableDeviceListSync();
let networkId = deviceInfoList[0].networkId;

// 定义访问公共文件目录的回调
let listeners : fs.DfsListeners = {
  onStatus: (networkId: string, status: number): void => {
    console.info('Failed to access public directory');
  }
}

// 访问并挂载公共文件目录
fs.connectDfs(networkId, listeners).then(() => {
  console.info("Success to connectDfs");
  let context = getContext(); // 获取设备B的UIAbilityContext信息
  let pathDir: string = context.distributedFilesDir;
  // 获取分布式目录的文件路径
  let filePath: string = pathDir + '/test.txt';

  try {
    // 打开分布式目录下的文件
    let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE);
    // 定义接收读取数据的缓存
    let arrayBuffer = new ArrayBuffer(4096);
    // 读取文件的内容,返回值是读取到的字节个数
    class Option {
        public offset: number = 0;
        public length: number = 0;
    }
    let option = new Option();
    option.length = arrayBuffer.byteLength;
    let num = fs.readSync(file.fd, arrayBuffer, option);
    // 打印读取到的文件数据
    let buf = buffer.from(arrayBuffer, 0, num);
    console.info('read result: ' + buf.toString());
  } catch (error) {
    let err: BusinessError = error as BusinessError;

  }
}).catch((error: BusinessError) => {
  let err: BusinessError = error as BusinessError;
  
});

3、断开链路

当设备B完成跨设备文件访问操作后,需及时断开设备间的链路,避免资源占用,具体实现代码如下所示:

import { BusinessError } from '@kit.BasicServicesKit';
import { distributedDeviceManager } from '@kit.DistributedServiceKit'
import { fileIo as fs } from '@kit.CoreFileKit';

// 获取设备A的networkId
let dmInstance = distributedDeviceManager.createDeviceManager("com.example.hap");
let deviceInfoList: Array<distributedDeviceManager.DeviceBasicInfo> = dmInstance.getAvailableDeviceListSync();
let networkId = deviceInfoList[0].networkId;

// 取消公共文件目录挂载
fs.disconnectDfs(networkId).then(() => {
  console.info("Success to disconnectDfs");
}).catch((error: BusinessError) => {
  let err: BusinessError = error as BusinessError;
  
})

实现跨设备文件拷贝

1、完成分布式组网

首先,将需要执行跨设备文件拷贝操作的所有设备接入同一局域网环境,同时完成同一鸿蒙账号的认证登录,确保设备间能够实现正常的分布式通信,完成组网准备。

2、拷贝跨设备文件

然后拷贝跨设备文件。同一应用在不同设备之间实现跨设备文件拷贝,核心逻辑与跨设备文件访问类似,需先将待拷贝文件移动至应用的分布式文件路径下。下面先展示设备A将自身沙箱文件拷贝至分布式路径下的具体操作,示例代码如下所示:

import { fileIo as fs } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { fileUri } from '@kit.CoreFileKit';

let context = getContext(this) as common.UIAbilityContext; // 获取设备A的UIAbilityContext信息
let pathDir: string = context.filesDir;
let distributedPathDir: string = context.distributedFilesDir;
// 待拷贝文件沙箱路径
let filePath: string = pathDir + '/src.txt';

try {
 // 文件不存在时,需要创建文件并写入内容
 let file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
 fs.writeSync(file.fd, 'Create file success');
 fs.closeSync(file);
} catch (error) {
}

// 获取待拷贝文件uri
let srcUri = fileUri.getUriFromPath(filePath);

// 将待拷贝的沙箱文件,拷贝到分布式目录下
let destUri: string = fileUri.getUriFromPath(distributedPathDir + '/src.txt');

try {
 // 将沙箱路径下的文件拷贝到分布式路径下
 fs.copy(srcUri, destUri).then(()=>{


 }).catch((error: BusinessError)=>{
   let err: BusinessError = error as BusinessError;

 })
} catch (error) {

}

接着当设备B需要获取设备A的沙箱文件时,只需从自身的分布式文件路径下,将对应的文件拷贝至目标沙箱路径即可,以此完成整个跨设备文件拷贝流程,具体操作代码如下所示:

import { fileIo as fs } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { fileUri } from '@kit.CoreFileKit';

let context = getContext(this) as common.UIAbilityContext; // 获取设备B的UIAbilityContext信息
let pathDir: string = context.filesDir;
let distributedPathDir: string = context.distributedFilesDir;
// 待拷贝文件的目标沙箱路径
let filePath: string = pathDir + '/dest.txt';

// 获取目标路径uri
let destUri = fileUri.getUriFromPath(filePath);

// 获取分布式路径下的源文件
let srcUri: string = fileUri.getUriFromPath(distributedPathDir + '/src.txt');

// 定义拷贝回调
let progressListener: fs.ProgressListener = (progress: fs.Progress) => {

};
let options: fs.CopyOptions = {
  "progressListener" : progressListener
}

try {
 // 将分布式路径下的文件拷贝到其他沙箱路径下
 fs.copy(srcUri, destUri, options).then(()=>{


 }).catch((error: BusinessError)=>{
   let err: BusinessError = error as BusinessError;

 })
} catch (error) {

}

结束语

通过本文的详细解析与实战代码演示,相信各位鸿蒙原生开发者已经清晰掌握了跨设备文件访问与拷贝的核心实现逻辑、操作步骤以及关键注意事项。在HarmonyOS全场景智能生态飞速发展的当下,跨设备文件操作能力早已不是“加分项”,而是鸿蒙原生应用适配多终端场景、提升用户体验的“必备项”,它不仅能够为用户提供无缝、高效的文件共享与传输体验,打破不同设备之间的资源壁垒,更能帮助开发者拓宽应用的适配场景,提升应用在鸿蒙生态中的核心竞争力。
随着HarmonyOS生态的不断迭代升级,分布式技术的应用场景也将更加广泛,跨设备文件操作的功能也将更加完善。未来,期待各位开发者能够将本文所学灵活运用到实际开发中,不断探索分布式技术的更多可能,开发出更多适配全场景需求、兼具实用性与创新性的鸿蒙原生应用,共同助力HarmonyOS原生生态的繁荣发展。同时也希望本文能够成为各位开发者的实用参考工具,在后续的跨设备开发工作中提供有力支撑,若在实操过程中遇到相关问题,可结合本文的步骤与代码进一步排查调试,稳步提升自身的鸿蒙原生开发能力。