HarmonyOS Next应用文件分享:安全高效的数据传递攻略 原创

mb6858ed302a25e
发布于 2025-6-23 14:01
浏览
0收藏

兄弟们,在App开发里,文件分享就像朋友间传文件——得方便又安全。HarmonyOS Next给咱们提供了两套方案:URI分享和FD分享,各有各的玩法。今天就聊聊怎么用这些功能,让用户传文件既顺畅又安全。

一、两种分享方式:URI和FD的区别

(一)URI分享:简单方便的"快递单号"

这种方式就像给文件弄个临时快递单号(URI),分享时不用直接传文件,对方拿单号就能取。好处是方便实现,而且分享后权限自动回收——对方App退出后,URI就失效了。但缺点是只能传单个文件,不能传文件夹。

(二)FD分享:直接递"钥匙"的高级玩法

FD相当于直接把文件的访问"钥匙"(文件描述符)给对方,支持传单个文件甚至文件夹。但这把"钥匙"有有效期——关闭FD后,对方就没法再访问了,用起来稍微复杂点。

(三)对比表格:按需选择

分享方式 优点 缺点 适用场景
URI分享 简单易用,自动回收权限 只能传单个文件 分享文本、图片等单个文件
FD分享 支持文件夹,性能更好 需要手动管理FD,关闭后失效 传大文件或文件夹

二、权限控制:没权限啥也干不了

(一)配置文件声明权限

要分享文件,先在module.json5里声明权限,就像跟系统报备:

"abilities": [
  {
    "name": "EntryAbility",
    "skills": [
      {
        "actions": [
          "ohos.arkui.intent.action.SEND_DATA"
        ],
        "uris": [
          {
            "scheme": "file",
            "host": "*",
            "path": "/storage/*"
          }
        ]
      }
    ]
  }
]

(二)动态申请授权

有些场景得跟用户要授权,比如访问相册:

import permission from '@ohos.permission';

async function requestFilePermission() {
  const result = await permission.requestPermissionsFromUser(
    this.context,
    ['ohos.permission.READ_USER_STORAGE']
  );
  if (result[0].granted) {
    // 有权限了,可以分享文件
  } else {
    // 没权限,提示用户去设置里开启
  }
}

三、代码实战:URI分享的完整流程

(一)分享文件:生成URI并发送

import { fileUri } from '@ohos.file.uri';
import { wantConstant, UIAbility } from '@ohos.app.ability';

export default class ShareAbility extends UIAbility {
  onWindowStageCreate() {
    // 1. 确定文件路径(比如沙箱里的test.txt)
    const filePath = this.context.filesDir + '/test.txt';
    
    // 2. 把路径转成URI(相当于给文件办个临时通行证)
    const uri = fileUri.getUriFromPath(filePath);
    
    // 3. 构造分享意图,带上读写权限
    const want = {
      flags: wantConstant.Flags.FLAG_AUTH_WRITE_URI_PERMISSION | 
             wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION,
      action: 'ohos.arkui.intent.action.SEND_DATA',
      uri: uri,
      type: 'text/plain' // 文件类型
    };
    
    // 4. 发起分享
    this.context.startAbility(want)
      .then(() => console.log('分享成功'))
      .catch(err => console.error('分享失败:', err));
  }
}

(二)接收文件:解析URI并使用

import { fileio as fs } from '@ohos.file.fs';

export default class ReceiveAbility extends UIAbility {
  onNewWant(want) {
    // 1. 拿到分享过来的URI
    const uri = want.uri;
    
    try {
      // 2. 打开文件(FD就是文件的操作句柄)
      const fd = fs.openSync(uri, fs.OpenMode.READ_WRITE);
      
      // 3. 读取文件内容(比如读文本文件)
      const buffer = new ArrayBuffer(1024);
      fs.readSync(fd, buffer);
      const content = new TextDecoder().decode(buffer);
      
      // 4. 处理内容...
      
      // 5. 用完关闭FD,释放资源
      fs.closeSync(fd);
    } catch (err) {
      console.error('处理分享文件出错:', err);
    }
  }
}

四、安全控制:别让文件"乱串门"

(一)权限粒度控制

别一股脑要所有权限,按需申请:

  • 只读文件:用FLAG_AUTH_READ_URI_PERMISSION
  • 可写文件:加FLAG_AUTH_WRITE_URI_PERMISSION

(二)敏感文件加密

传银行卡照片、合同之类的敏感文件,得加密:

import crypto from '@ohos.security.crypto';

async function encryptFile(filePath) {
  // 1. 生成AES密钥
  const key = await crypto.generateKey(
    { algorithm: 'AES', length: 256 },
    true,
    ['encrypt', 'decrypt']
  );
  
  // 2. 读取文件
  const fd = fs.openSync(filePath, fs.OpenMode.READ);
  const buffer = new ArrayBuffer(fs.getSizeSync(fd));
  fs.readSync(fd, buffer);
  fs.closeSync(fd);
  
  // 3. 加密
  const cipher = await crypto.createCipher(
    { algorithm: 'AES/CBC/PKCS7Padding' },
    key
  );
  const encrypted = await cipher.encrypt(new Uint8Array(buffer));
  
  // 4. 保存加密文件
  const encryptedPath = filePath + '.enc';
  const encryptFd = fs.openSync(encryptedPath, fs.OpenMode.CREATE | fs.OpenMode.WRITE);
  fs.writeSync(encryptFd, encrypted);
  fs.closeSync(encryptFd);
  
  return encryptedPath;
}

(三)分享日志记录

记好分享日志,出问题能追查:

// 分享成功后记录
log.info('文件分享记录', {
  userId: '12345',
  fileName: 'contract.pdf',
  shareTime: new Date().toISOString(),
  targetApp: 'com.example.wechat'
});

五、实战踩坑指南

(一)URI分享常见问题

  1. 权限失效:分享后对方App没及时用URI,过一会儿就失效了。解决办法是给用户提示,让对方尽快操作。
  2. 文件不存在:分享后删除了原文件,对方打开报错。得在分享时做文件存在性检查,或者复制一份再分享。

(二)FD分享注意事项

  1. FD关闭问题:FD关闭后,对方就没法访问了。建议在分享时给FD设置合理的生命周期,比如用try-finally确保关闭。
  2. 性能优化:传大文件时别一次性读入内存,用流式传输,不然容易OOM。

(三)安全隐患

  1. 未授权访问:别把URI随便传给未授权的App。分享时最好限定目标App的包名,比如:
const want = {
  // 其他配置...
  bundleName: 'com.example.targetapp' // 限定只能传给这个App
};

六、总结:选对工具,安全第一

HarmonyOS Next的文件分享有两套方案:

  • URI分享适合简单场景,自动管理权限
  • FD分享适合传文件夹或大文件,性能更好

开发时记住:

  1. 权限别乱要,够用就行
  2. 敏感文件一定加密
  3. 做好异常处理和日志记录
  4. 给用户清晰的操作提示

把这些点做好,用户传文件就跟喝水一样自然,还不用担心安全问题。下次做文件分享功能,记得按这个路子来,少踩坑!

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
标签
收藏
回复
举报
回复
    相关推荐