• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 跨设备文件拷贝
2
3分布式文件系统为应用提供了跨设备文件拷贝的能力,开发者在跨设备跨应用进行文件拷贝时,通过[基础文件接口](../reference/apis-core-file-kit/js-apis-file-fs.md),可跨设备跨应用拷贝文件。例如:多设备数据流转的场景,设备组网互联之后,设备A上的应用可在复制时,将A设备的沙箱文件,拷贝到A设备的分布式路径下,设备B在粘贴的时候,从设备B的分布式路径下,将文件拷贝到对应的沙箱文件中。
4
5## 开发步骤
6
71. 完成分布式组网。
8   首先将需要进行跨设备访问的设备连接到同一局域网中,同账号认证完成组网。
9
102. 授权分布式数据同步权限。
11   分布式数据同步权限的授权方式为user_grant,因此需要调用requestPermissionsFromUser接口,以动态弹窗的方式向用户申请授权。示例中的context的获取方式请参见[获取UIAbility的上下文信息](../application-models/uiability-usage.md#获取uiability的上下文信息)。
12
13   ```ts
14   import { common, abilityAccessCtrl } from '@kit.AbilityKit';
15   // 请在组件内获取context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext
16   let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
17   let atManager = abilityAccessCtrl.createAtManager();
18   try {
19     atManager.requestPermissionsFromUser(context, ['ohos.permission.DISTRIBUTED_DATASYNC']).then((data) => {
20       console.log(`data: ${JSON.stringify(data)}`);
21     }).catch((err: object) => {
22       console.log(`err: ${JSON.stringify(err)}`);
23     })
24   } catch (err) {
25     console.log(`catch err-> ${JSON.stringify(err)}`);
26   }
27   ```
28
293. 执行跨设备文件拷贝操作。
30   同一应用不同设备之间实现跨设备文件拷贝,只需要将对应的文件放在应用沙箱的分布式文件路径即可。
31
32   将A设备的待拷贝沙箱文件,拷贝到A设备的分布式路径下。
33
34   ```ts
35   import { fileIo as fs } from '@kit.CoreFileKit';
36   import { common } from '@kit.AbilityKit';
37   import { BusinessError } from '@kit.BasicServicesKit';
38   import { fileUri } from '@kit.CoreFileKit';
39
40   // 请在组件内获取context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext
41   let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
42   let pathDir: string = context.filesDir;
43   let distributedPathDir: string = context.distributedFilesDir;
44   // 待拷贝文件沙箱路径
45   let filePath: string = pathDir + '/src.txt';
46   try {
47    // 准备待拷贝沙箱文件
48    let file = fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
49    fs.writeSync(file.fd, 'Create file success');
50    fs.closeSync(file);
51   } catch (error) {
52    console.error(`Failed to createFile. Code: ${error.code}, message: ${error.message}`);
53   }
54
55   // 获取待拷贝源文件uri
56   let srcUri = fileUri.getUriFromPath(filePath);
57   // 获取目标路径(分布式路径)的uri
58   let destUri: string = fileUri.getUriFromPath(distributedPathDir + '/src.txt');
59   try {
60     // 将沙箱路径下的源文件拷贝到目标分布式路径下
61     fs.copy(srcUri, destUri).then(()=>{
62       console.info(`Succeeded in copying---. `);
63       console.info(`src: ${srcUri} dest: ${destUri}`);
64     }).catch((error: BusinessError)=>{
65       let err: BusinessError = error as BusinessError;
66       console.info(`Failed to copy. Code: ${err.code}, message: ${err.message}`);
67     })
68   } catch (error) {
69     console.error(`Failed to getData. Code: ${error.code}, message: ${error.message}`);
70   }
71   ```
72
73   B设备在获取A端沙箱文件时,从B设备的分布式路径下将对应的文件拷贝走,以此完成跨设备拷贝。
74
75   ```ts
76   import { fileIo as fs } from '@kit.CoreFileKit';
77   import { common } from '@kit.AbilityKit';
78   import { BusinessError } from '@kit.BasicServicesKit';
79   import { fileUri } from '@kit.CoreFileKit';
80   import { distributedDeviceManager } from '@kit.DistributedServiceKit'
81
82   // context是EntryAbility传过来的context,确保this.getUIContext().getHostContext()返回结果为UIAbilityContext
83   let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
84   let pathDir: string = context.filesDir;
85   let distributedPathDir: string = context.distributedFilesDir;
86   // 待拷贝文件的目标路径(沙箱路径)
87   let destPath: string = pathDir + '/dest.txt';
88   // 获取目标路径uri
89   let destUri = fileUri.getUriFromPath(destPath);
90
91   // 拷贝源文件路径(分布式路径)
92   let srcPath = distributedPathDir + '/src.txt';
93   // 获取源路径uri
94   let srcUri: string = fileUri.getUriFromPath(srcPath);
95
96   // 定义拷贝回调
97   let progressListener: fs.ProgressListener = (progress: fs.Progress) => {
98     console.info(`progressSize: ${progress.processedSize}, totalSize: ${progress.totalSize}`);
99   };
100   let options: fs.CopyOptions = {
101     "progressListener" : progressListener
102   }
103   // 通过分布式设备管理的接口获取设备A的networkId信息
104   let dmInstance = distributedDeviceManager.createDeviceManager("com.example.hap");
105   let deviceInfoList: Array<distributedDeviceManager.DeviceBasicInfo> = dmInstance.getAvailableDeviceListSync();
106   if (deviceInfoList && deviceInfoList.length > 0) {
107    console.info(`success to get available device list`);
108    let networkId = deviceInfoList[0].networkId; // 这里只是两个设备连接,列表中首个即为A设备的networkId
109    // 定义访问分布式目录的回调
110    let listeners : fs.DfsListeners = {
111      onStatus: (networkId: string, status: number): void => {
112        console.info(`Failed to access public directory`);
113      }
114    }
115    // 开始跨设备文件访问
116    fs.connectDfs(networkId, listeners).then(()=>{
117      try {
118        // 将分布式路径下的文件拷贝到其他沙箱路径下
119        fs.copy(srcUri, destUri, options).then(()=>{
120          console.info(`Succeeded in copying from distribted path`);
121          console.info(`src: ${srcUri} dest: ${destUri}`);
122          fs.unlinkSync(srcPath); // 拷贝完成后清理分布式路径下的临时文件
123        }).catch((error: BusinessError)=>{
124          let err: BusinessError = error as BusinessError;
125          console.info(`Failed to copy. Code: ${err.code}, message: ${err.message}`);
126        })
127      } catch (error) {
128        console.error(`Failed to copy. Code: ${error.code}, message: ${error.message}`);
129      }
130    })
131   }
132   ```
133
1344. 跨设备文件拷贝完成,断开链路。
135
136   ```ts
137   import { BusinessError } from '@kit.BasicServicesKit';
138   import { distributedDeviceManager } from '@kit.DistributedServiceKit'
139   import { fileIo as fs } from '@kit.CoreFileKit';
140
141   // 获取设备A的networkId
142   let dmInstance = distributedDeviceManager.createDeviceManager("com.example.hap");
143   let deviceInfoList: Array<distributedDeviceManager.DeviceBasicInfo> = dmInstance.getAvailableDeviceListSync();
144   if (deviceInfoList && deviceInfoList.length > 0) {
145    let networkId = deviceInfoList[0].networkId; // 这里只是两个设备连接,列表中首个即为A设备的networkId
146    // 关闭跨设备文件访问
147    fs.disconnectDfs(networkId).then(() => {
148      console.info(`Success to disconnectDfs`);
149    }).catch((error: BusinessError) => {
150      let err: BusinessError = error as BusinessError;
151      console.error(`Failed to disconnectDfs Code: ${err.code}, message: ${err.message}`)
152    })
153   }
154   ```