场景描述:

我们经常通过文件管理器使用三方应用对文件进行读写,具体该如下。

场景一:

从文件管理器打开文件,选择三方应用打开。

<p id="p17338194319463">后缀名</p> <p id="p1433834314465">MIMEType</p>
<p id="p163388437461">txt</p> <p id="p1433811437463">text/plain</p>
<p id="p1933812435464">xlsx</p> <p id="p9338154364610">application/vnd.openxmlformats-officedocument.spreadsheetml.sheet</p>
<p id="p933874317464">png</p> <p id="p4338154324615">image/png</p>
<p id="p17338174317465">mp3</p> <p id="p18338943134616">audio/mpeg</p>
<p id="p4338243114613">java</p> <p id="p5338443134616">text/x-java</p>

1 、应用需要在module.json5配置文件的actions标签的值配置为"ohos.want.action.viewData",表示接收应用分享文件,配置uris字段,表示接收URI的类型,即只接收其他应用分享该类型的URI,如下表示本应用只接收scheme为file,类型为txt的文件。

2 、被分享方的UIAbility被启动后,可以在其onCreate()或者onNewWant回调中获取传入的Want参数信息,通过接口want的参数获取分享文件的URI,获取文件URI后通过fs.open接口打开文件,获取对应的file对象后,可对文件进行读写操作。

3 、引用了三方库@changwei/chardet,实现对特定编码格式进行自动识别。

效果图

关键步骤

第一步:被分享应用需要在module.json5配置文件的actions标签的值配置为"ohos.want.action.viewData",表示接收应用分享文件,配置uris字段,表示接收URI的类型,即只接收其他应用分享该类型的URI,如下表示本应用只接收scheme为file,类型为txt的文件。(type值设置查看文章顶部链接,scheme同一设置为file,表示接受文件)。

"module": {
  ...
  "abilities": [
    {
      ...
      "skills": [
        {
          ...
          "actions": [
            "ohos.want.action.viewData"
          ],
          "uris": [
            {
              "scheme": "file",
              "type": "text/plain"
            },
            {
              "scheme": "file",
              "type": "image/png"
            },
            {
              "scheme": "file",
              "type": "text/h323"
            },
          ]
        }
      ]
    }
  ]
}

第二步:被分享方的UIAbility被启动后,可以在其onCreate()或者onNewWant回调中获取传入的Want参数信息。

通过接口want的参数获取分享文件的URI,获取文件URI后通过fs.open接口打开文件,获取对应的file对象后,可对文件进行读写操作。此处引用了三方库@changwei/chardet,详情见识别并显示特定编码格式的文件部分。

import fs from '@ohos.file.fs';
import Want from '@ohos.app.ability.Want';
import { BusinessError } from '@ohos.base';
import { util } from '@kit.ArkTS';
import * as chardet from '@changwei/chardet';

getShareFileText(Uri: string):string {
  // let want: Want = Uri; // 此处实际使用时应该修改为获取到的分享方传递过来的want信息
  // 从want信息中获取uri字段
  let uri = Uri;
  if (uri == null || uri == undefined) {
    console.info('uri is invalid');
    return "";
  }
  let point = uri.lastIndexOf(".")
  let typ = uri.slice(point)
  // 根据需要对被分享文件的URI进行相应操作。例如读写的方式打开URI获取file对象
  let file = fs.openSync(uri, fs.OpenMode.READ_WRITE);
  let arrayBuffer = new ArrayBuffer(1024)
  fs.readSync(file.fd,arrayBuffer)
  let charset = chardet.detect(new Uint8Array(arrayBuffer, 0, 512));
  let textDecoder = util.TextDecoder.create(charset);
  let result = new Uint8Array(arrayBuffer);
  return textDecoder.decodeWithStream(result);
}

场景二:

识别并显示特定编码格式的文件

效果图

<p id="p1093298622">编码</p> <p id="p5932581219">介绍</p>
<p id="p13932281321">Unicode</p> <p id="p179321181211">Unicode是一种多语言编码格式,用于表示和传输各种语言的文本数据。</p>
<p id="p129321810212">UTF-8</p> <p id="p19933168628">UTF-8是一种变长编码格式,用于表示和传输Unicode文本数据。</p>
<p id="p1093328228">GB2312</p> <p id="p1493316811212">GB2312是一种中文编码格式,用于表示和传输中文文本数据。</p>
<p id="p149331281224">UTF-16</p> <p id="p693311819217">UTF-16是一种变长编码格式,用于表示和传输Unicode文本数据。</p>
<p id="p1993311816215">ANSI</p> <p id="p199331781325">ANSI是一种美国国家标准协会制定的编码格式,用于表示和传输美国英语文本数据。</p>
<p id="p119331081729">GBK</p> <p id="p1493314817211">是指中国的中文字符,其它它包含了简体中文与繁体中文字符,另外还有一种字符“gb2312”,这种字符仅能存储简体中文字符。</p>
<p id="p12933582020">ASCII</p> <p id="p593348629">ASCII是一种通用的编码格式,用于表示和传输文本数据</p>

关键步骤

第一步:安装三方库依赖。

ohpm install @changwei/chardet

第二步:在代码中引入使用,返回最可能的字符编码。

import fs from '@ohos.file.fs'

let file=fs.openSync('/path/to/file',fs.OpenMode.READ_ONLY);
let arrayBuffer=new ArrayBuffer(1024);// 读取文本文件内容
let readLen = fs.readSync(file.fd, arrayBuffer,{
  offset: 0,
  length: arrayBuffer.length
});
// 提取前512个字节内容以提高性能,长文本建议这样做
let charset = chardet.detect(new Uint8Array(arrayBuffer, 0, 512));
// or
const encoding = await chardet.detectFile('/path/to/file');
// or
const encoding = chardet.detectFileSync('/path/to/file');

常见问题

Q:如何通过文件后缀获取对应的MIMEType列表?

A:下面以通过“.mp3”文件后缀获取对应的MIMEType列表为例,说明如何通过文件后缀获取对应的MIMEType列表。

1、导入@ohos.data.uniformTypeDescriptor模块。

2、可根据 “.mp3” 文件后缀查询对应UTD数据类型。

3、根据UTD数据类型查询对应的MIMEType列表。

import uniformTypeDescriptor from '@ohos.data.uniformTypeDescriptor';
try {
  // 可根据.mp3文件后缀查询对应UTD数据类型。
  let fileExtention = '.mp3';
  let typeId = uniformTypeDescriptor.getUniformDataTypeByFilenameExtension(fileExtention);
  // 根据UTD数据类型查询对应的MIMEType列表。
  let typeObj = uniformTypeDescriptor.getTypeDescriptor(typeId);
  let mimeTypes = typeObj.mimeTypes;
  console.info('mimeTypes:' + mimeTypes);
} catch (err) {
  console.error('err message:' + err.message + ', err code:' + err.code);
}

Q:如何通过MIMEType获取对应的后缀列表?

A:下面以通过“audio/mp3”MIMEType获取对应文件后缀列表为例,说明如何通过MIMEType获取对应的后缀列表。

1、导入@ohos.data.uniformTypeDescriptor模块。

2、可根据 “audio/mp3” MIMEType查询对应UTD数据类型。

3、根据UTD数据类型查询对应的后缀列表。

import uniformTypeDescriptor from '@ohos.data.uniformTypeDescriptor';
try {
  // 可根据audio/mp3MIMEType查询对应UTD数据类型。
  let mineType = 'audio/mp3';
  let typeId = uniformTypeDescriptor.getUniformDataTypeByMIMEType(mineType);
  // 根据UTD数据类型查询对应的MIMEType列表
  let typeObj = uniformTypeDescriptor.getTypeDescriptor(typeId);
  let filenameExtensions = typeObj.filenameExtensions;
  console.info('filenameExtensions:' + filenameExtensions);
} catch (err) {
  console.error('err message:' + err.message + ', err code:' + err.code);
}

Q:如何控制文件读写权限?

A:基于URI分享方式,应用可分享单个文件,通过ohos.app.ability.wantConstant的wantConstant.Flags接口以只读或读写权限授权给其他应用。应用可通过ohos.file.fs的open接口打开URI,并进行读写操作。当前仅支持临时授权,分享给其他应用的文件在被分享应用退出时权限被收回。

基于FD分享方式,应用可分享单个文件,通过ohos.file.fs的open接口以指定权限授权给其他应用。应用从Want中解析拿到FD后可通过ohos.file.fs的读写接口对文件进行读写。


HarmonyOS码上奇行
7k 声望2.8k 粉丝