【HarmonyOS】API9中datashare转internal的方法

发布时间 2023-06-05 11:45:05作者: Mayism123
【前言】

HarmonyOS 3.1 Release版本正式发布了,这个版本给我们带来了一个非常有用的API——FilePicker(文件选择器) @ohos.file.picker,使用这个API我们可以选取手机中的图片视频等用于分享,并且不需要配置任何权限就可以使用。具体的使用方法就不赘述了,官网可以看选择用户文件保存用户文件这两个文档,文档中有具体的说明。我们通过FilePicker(文件选择器)可以获取一个文件资源uri(如:datashare:///media/image/2),使用文件接口(@ohos.file.fs)就可以读写这个uri对应的文件。这给我们开发带来了极大的便利。

 

【问题】

然而3.1系统中有一些接口仍然使用的是“internal"协议如下图中,上传接口UploadConfig仅支持"internal"格式,"internal"对应的是应用内部的文件。但是文件选择器选返回的是"datashare"格式,对应的是应用外部的文件,那这该如何转换呢

cke_4015.png​​

 

【解决方案】

首先需要确认的是"internal路径"与"应用开发路径"之间的关系。以上传接口为例,internal://cache/目录对应的就是从Context中获取的应用开发路径cacheDir(应用内部存储中的缓存路径)。

也就是说下面两个路径对应的是同一个文件

路径1:

let context =getContext(this) as common.UIAbilityContext

let cacheDir =context.cacheDir

let path =cacheDir+"/dest.txt"

路径2:

let path ="internal://cache/dest.txt"

确认完这点以后我们只需要把外部的文件复制到cacheDir目录下就可以了,具体代码如下:

try {
 let URI = null;
 let DocumentSelectOptions = new picker.DocumentSelectOptions();
 let documentPicker = new picker.DocumentViewPicker();
 documentPicker.select(DocumentSelectOptions).then((documentSaveResult) => {
   URI = documentSaveResult[0];
   console.info('documentViewPicker.select to file succeed and URI is:' + URI);
   let srcFile = fs.openSync(URI, fs.OpenMode.READ_WRITE);
   let destFile = fs.openSync(cacheDir+"/dest.txt",fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
   // 读取源文件内容并写入至目的文件
   let bufSize = 4096;
   let readSize = 0;
   let buf = new ArrayBuffer(bufSize);
   let readLen = fs.readSync(srcFile.fd, buf, { offset: readSize });
   while (readLen > 0) {
     readSize += readLen;
     fs.writeSync(destFile.fd, buf);
     readLen = fs.readSync(srcFile.fd, buf, { offset: readSize });
   }
   // 关闭文件
   fs.closeSync(srcFile);
   fs.closeSync(destFile);

 }).catch((err) => {
   console.error('documentViewPicker.select failed with err: ' + err);
 });
} catch (err) {
 console.error('documentViewPicker failed with err: ' + err);
}

这样我们就完成了datashare到internal的转换,可以使用"internal://cache/dest.txt"去做想要的操作了。