1. 分布式文件系统概述
分布式文件系统(hmdfs,HarmonyOS Distributed File System)提供跨设备的文件访问能力,适用于如下场景:
两台设备组网,用户可以利用一台设备上的编辑软件编辑另外一台设备上的文档。
平板保存的音乐,车载系统直接可见并可播放。
户外拍摄的照片,回家打开平板直接访问原设备拍摄的照片。
hmdfs在分布式软总线动态组网的基础上,为网络上各个设备结点提供一个全局一致的访问视图,支持开发者通过基础文件系统的接口进行读写访问,具有高性能、低延时等优点。
2. 设置分布式文件等级
不同设备本身的安全能力差异较大,因此,HarmonyOS提供一套完整的数据分级、设备分级标准,并针对不同设备制定不同的数据流转策略。 官方提供的API:setSecurityLabel
使用方式:
-----------------------------------
https://blog.51cto.com/u_17287091/13451072
//打开文件 let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); // 设置文件的数据等级为s0 securityLabel.setSecurityLabel(filePath, 's0').then(() => { console.info('Succeeded in setSecurityLabeling.'); fs.closeSync(file); }).catch((err: BusinessError) => { console.error(`Failed to setSecurityLabel. Code: ${err.code}, message: ${err.message}`); });
3. 跨设备文件访问
分布式文件系统为应用提供了跨设备文件访问的能力,开发者在两个设备安装同一应用时,通过基础文件接口,可跨设备读写另一个设备该应用分布式文件路径(/data/storage/el2/distributedfiles/)下的文件。例如:多设备数据流转的场景,设备组网互联之后,设备A上的应用可访问设备B同应用分布式路径下的文件,当期望应用文件被其他设备访问时,只需将文件移动到分布式文件路径即可。
使用步骤:
1. 完成组网
将需要跨设备访问的两个设备登录同一账号,保证设备蓝牙和Wi-Fi功能开启,蓝牙无需互连,Wi-Fi无需接入同一个局域网。
2. 访问跨设备文件
同一应用不同设备之间实现跨设备文件访问,只需要将对应的文件放在应用沙箱的分布式文件路径即可。
2.1 设备A在分布式下创建文件:
-----------------------------------
async createDistributedFile(uri: string) { let context = getContext(this) as common.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); console.info('Succeeded in createing.'); // 向文件中写入内容 fs.writeSync(file.fd, 'content'); // 关闭文件 fs.closeSync(file.fd); } catch (error) { let err: BusinessError = error as BusinessError; console.error(`Failed to openSync / writeSync / closeSync. Code: ${err.code}, message: ${err.message}`); } }
/** * 拉起picker保存文件 */ async saveFile(fileName: string):Promise<string>{ // fileName = this.tempFilePath; ('保存的文件名:' + fileName) let saveFileUri = '' try { let DocumentSaveOptions = new picker.DocumentSaveOptions(); DocumentSaveOptions.newFileNames = [fileName]; let documentPicker = new picker.DocumentViewPicker(); await documentPicker.save(DocumentSaveOptions).then( (DocumentSaveResult) => { ('DocumentViewPicker.save successfully, DocumentSaveResult uri: ' + JSON.stringify(DocumentSaveResult)); if (DocumentSaveResult !== null && DocumentSaveResult !== undefined) { let uri = DocumentSaveResult[0] as string; ('分布式',`save file uri: ${uri}`); this.realFileUri = uri this.realSaveFile(fileName) saveFileUri = uri } }).catch((err: BusinessError) => { PhLog.error('saveFile-DocumentViewPicker.save failed with err: ' + JSON.stringify(err)); }); } catch (err) { PhLog.error('saveFile-DocumentViewPicker failed with err: ' + err); } return saveFileUri } realFileUri: string = '' /** * 真正开始保存文件 */ async realSaveFile(fileName: string) { // let fileName = this.tempFilePath; let context = getContext(this) as common.UIAbilityContext; // 获取设备B的UIAbilityContext信息 let pathDir = context.distributedFilesDir; // 获取分布式目录的文件路径 let filePath = pathDir + '/' + fileName; ('保存文件时候读取的文件路径:' + filePath) //开始写入内容 let startSaveFileTask: taskpool.Task = new taskpool.Task(startSaveFile3, filePath,this.realFileUri); taskpool.execute(startSaveFileTask).then((writtenSize: number) => { if (writtenSize > 0) { console.info('分布式',`文件写入成功,写入大小: ${writtenSize} 字节`); promptAction.showToast({ message: '文件保存成功' }) } else { console.error('分布式','文件写入失败'); } this.deleteDistributedFile(filePath) }) @Concurrent export async function startSaveFile3(filePath: string, realFileUri: string): Promise<number> { try { // 读取源文件 const sourceFile = fs.openSync(filePath, fs.OpenMode.READ_ONLY); const stats = await fs.stat(filePath); const fileSize = stats.size; ('分布式', `保存的文件: ${filePath} - 大小:${fileSize}`); // 目标文件 const targetFile = fs.openSync(realFileUri, fs.OpenMode.WRITE_ONLY); // 分片大小,可根据实际情况调整 const chunkSize = 1024 * 1024*20; // 1MB let offset = 0; let totalWritten = 0; while (offset < fileSize) { const currentChunkSize = Math.min(chunkSize, fileSize - offset); const buffer = new ArrayBuffer(currentChunkSize); ('分布式','01开始读取:'+s) // 读取当前分片的数据 const readLen = fs.readSync(sourceFile.fd, buffer, { offset }); if (readLen === 0) { break; } // 写入当前分片的数据 const writeLen = await fs.write(targetFile.fd, buffer, { offset }); totalWritten += writeLen; offset += writeLen; // 计算并调用进度回调 const progress = (totalWritten / fileSize) * 100; ('分布式', `写入进度: ${progress.toFixed(2)}%`); } // 关闭文件 fs.closeSync(sourceFile); fs.closeSync(targetFile); return totalWritten; } catch (error) { PhLog.error('分布式', `保存文件时出错: ${error.message}`); return -1; } }
到这里就完成了分布式文件的访问、拷贝,整体流程就是:
A设备创建分布式文件,写入内容
B设备从分布式文件系统目录上读取文件内容
将文件保存到本地
PS:操作文件时候注意添加相关权限
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70015403/viewspace-3107357/ ,如需转载,请注明出处,否则将追究法律责任。