积分48 / 贡献0

提问0答案被采纳0文章4

[经验分享] OpenHarmony应用基于分布式文件系统及分布式数据对象实现跨设备文件的拷贝

深开鸿_王肖云 显示全部楼层 发表于 2024-1-2 15:06:51

OpenHarmony应用基于分布式文件系统及分布式数据对象实现跨设备文件的拷贝

简介:

利用分布式组网成功后,分布式文件系统的共享特征,以及分布式数据对象的实时同步性,将要拷贝的文件首先通过fs.copy接口拷贝至分布式文件系统路径下,同时更新分布式数据对象将此次的拷贝文件信息进行更新。组网内其他设备或本设备,可通过分布式数据对象知道拷贝对象及位置信息,再次利用fs.copy接口将分布式文件系统下的文件拷贝至本设备。

copy.png

分布式数据对象中的字段定义及作用如下: from: '', ----该分布式对象的发送设备ID,用于设备判断该对象是本设备还是跨设备。 localFileUriList: [],--往分布式文件系统拷贝时的当前文件uri路径,如果是文件,前面会增加“file+”前缀。本设备拷贝时用这个字段作为copy的入参。 disFileUriList: [],--uri化的分布式文件路径,如果是文件,前面会增加“file+”前缀。跨设备拷贝时用此字段作为copy的入参。 disFileList: [], --没有uri化的分布式文件路径,该字段用于拷贝完后分布式文件系统下的文件清理。

文档环境:

  • 开发环境:Windows 10专业版
  • DevEco Studio版本:DevEco Studio 4.0Release (4.0.0.600)
  • SDK版本:4.1.3.3 (full sdk)
  • API版本:Version 11
  • 开发板型号:DAYU200(RK3568)
  • 系统版本:OpenHarmony 4.1.3.5

演示demo:

  • 新建一个 Stage 框架的 demo 工程,在page/Index.ets中通过 let context = getContext(this) as common.UIAbilityContext;filePath = context.filesDir; 拿到应用的沙箱files路径信息,通过文件操作接口在files下创建文件夹test1,test2,并在文件夹test1下创建了文件file1.txt,file2.txt,file3.txt。

  • 通过封装好的DataObject进行分布式数据对象的更新、清除等操作。

  • 通过接口fs.copy进行本应用沙箱内与分布式文件系统之间的文件(夹)拷贝。

  • demo运行效果:

    progress.png

    核心代码如下:

    pasteFromDistributedDir(deviceId: string, directoryPath:string, fileData: Array<FileStructure>) {
    let localDstUri = fileuri.getUriFromPath(directoryPath);
    if (this.distributedObject["disFileUriList"].length === 0) {
    return prompt.showToast({ message: \$r('app.string.label\_nodata') });
    }
    //本地拷贝:文件需进行重命名操作
    if (deviceId == this.distributedObject["from"]) {
    let localFileArray: Array<string> = this.distributedObject["localFileUriList"];
    let newFileName:string = '';
    localFileArray.forEach( item  => {
    //判断uri前缀是否有“file+”,如果是文件类型,去掉“file+”前缀,在localDstUri后面加上文件名称
    if (item.includes("file+")) {
    item = item.substring(5, item.length);
    let fileName: string | undefined = item.split('/').pop();
    if(fileName)
    {
    newFileName = fileName;
    } else {
    return;
    }
    //判断本地是否有同名文件,有则重命名
    fileData.forEach(file => {
    //有同名文件
    if(file.name.includes(newFileName)){
    //extension 文件后缀
    let extension :string = newFileName.slice((newFileName.lastIndexOf(".") - 1 >>> 0) + 2);
    if(extension){
    let fileParts = newFileName.split('.');
    newFileName = fileParts[0] + fileCopy + '.' + fileParts[1];
    } else {
    newFileName = newFileName + fileCopy;
    }
    }
    })
    }
    FsManager.pasteFromDistributedDir(item,localDstUri+newFileName);
    })
    } else { //跨设备拷贝
    let disFileUriArray: Array<string> = this.distributedObject["disFileUriList"];
    disFileUriArray.forEach( item  => {
    if (item.includes("file+")) {
    item = item.substring(5, item.length);
    let fileName: string | undefined = item.split('/').pop();
    let newFileName: string = '';
    if(fileName)
    {
    newFileName = fileName;
    } else {
    return;
    }
    FsManager.pasteFromDistributedDir(item,localDstUri+newFileName);
    } else {
    FsManager.pasteFromDistributedDir(item,localDstUri);
    }
    })
    }
    }
    
    copyFilesToDistributedDir(deviceId: string, needMoveFiles: Array<FileType>, disPathInSandbox: string) {
    let distributedUri0 = fileuri.getUriFromPath(disPathInSandbox);
    let localFileUriList: Array<string> = [];
    let disFileUriList: Array<string> = [];
    let disFileList: Array<string> = [];
    let distributedUri = '';
    needMoveFiles.forEach((file: FileType) => {
    //用于粘贴完后的clear动作中
    let disFilePath = disPathInSandbox + "/" + file.fileName;
    //type: 1 directory,type 2 file
    let localSrcUri = fileuri.getUriFromPath(file.filePath);
    //如果是文件夹
    if (file.type === 1) {
    distributedUri = distributedUri0+ "/" + file.fileName;
    FsManager.copyFilesToDistributedDir(localSrcUri,distributedUri);
    }
    //处理Uri,如果是文件类型,需另外处理,前缀增加"file+",用分布式对象进行传输
    else if (file.type === 2) {
    const fileName = localSrcUri.split('/').pop();
    distributedUri = distributedUri0 +"/"+fileName;
    FsManager.copyFilesToDistributedDir(localSrcUri,distributedUri);
    localSrcUri = "file+" + localSrcUri;
    distributedUri = "file+" + distributedUri;
    } else {
    Logger.error(TAG, \`this is not file or directory\`);
    }
    // to update DataObject
    localFileUriList.push(localSrcUri);
    disFileUriList.push(distributedUri);
    disFileList.push(disFilePath);
    })
    this.update(deviceId,localFileUriList,disFileUriList,disFileList);
    }
    }

sample仓地址:

本功能的sample仓地址:https://gitee.com/openharmony/applications\_app\_samples/tree/master/code/SuperFeature/DistributedAppDev/DistributedFilemanager

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

精彩评论1

applepai

沙发 发表于 3 天前

OpenHarmony应用基于分布式文件系统及分布式数据对象实现跨设备文件的拷贝

你好,我想请教一下分布式对象的使用必须要在同一局域网并且登录华为账号吗,我无法监听到分布式对象数据的变化

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部