HarmonyOS NEXT - 应用文件访问与管理

饭宝  论坛元老 | 2024-12-2 15:49:31 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 1032|帖子 1032|积分 3096

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
应用文件访问(ArkTS)
 


应用需要对应用文件目录下的应用文件举行检察、创建、读写、删除、移动、复制、获取属性等访问操作,下文介绍详细方法。
接口说明

开发者通过基础文件操作接口(ohos.file.fs)实现应用文件访问能力,重要功能如下表所示。
表1 基础文件操作接口功能

 
接口名功能接口范例支持同步支持异步access查抄文件是否存在方法√√close关闭文件方法√√copyFile复制文件方法√√createStream基于文件路径打开文件流方法√√listFile列出文件夹下全部文件名方法√√mkdir创建目录方法√√moveFile移动文件方法√√open打开文件方法√√read从文件读取数据方法√√rename重定名文件或文件夹方法√√rmdir删除整个目录方法√√stat获取文件详细属性信息方法√√unlink删除单个文件方法√√write将数据写入文件方法√√Stream.close关闭文件流方法√√Stream.flush刷新文件流方法√√Stream.write将数据写入流文件方法√√Stream.read从流文件读取数据方法√√File.fd获取文件形貌符属性--OpenMode设置文件打开标签属性--Filter设置文件过滤设置项范例--  
开发示例

在对应用文件开始访问前,开发者需要获取应用文件路径。以从UIAbilityContext获取HAP级别的文件路径为例举行说明,UIAbilityContext的获取方式请参见获取UIAbility的上下文信息。
下面介绍几种常用操作示例。
新建并读写一个文件

以下示例代码演示了如何新建一个文件并对其读写。
  1. // pages/xxx.ets
  2. import { fileIo as fs, ReadOptions } from '@kit.CoreFileKit';
  3. import { common } from '@kit.AbilityKit';
  4. import { buffer } from '@kit.ArkTS';
  5. // 获取应用文件路径
  6. let context = getContext(this) as common.UIAbilityContext;
  7. let filesDir = context.filesDir;
  8. function createFile(): void {
  9.   // 新建并打开文件
  10.   let file = fs.openSync(filesDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  11.   // 写入一段内容至文件
  12.   let writeLen = fs.writeSync(file.fd, "Try to write str.");
  13.   console.info("The length of str is: " + writeLen);
  14.   // 从文件读取一段内容
  15.   let arrayBuffer = new ArrayBuffer(1024);
  16.   let readOptions: ReadOptions = {
  17.     offset: 0,
  18.     length: arrayBuffer.byteLength
  19.   };
  20.   let readLen = fs.readSync(file.fd, arrayBuffer, readOptions);
  21.   let buf = buffer.from(arrayBuffer, 0, readLen);
  22.   console.info("the content of file: " + buf.toString());
  23.   // 关闭文件
  24.   fs.closeSync(file);
  25. }
复制代码
读取文件内容并写入到另一个文件

以下示例代码演示了如何从一个文件读写内容到另一个文件。

 
  1. // pages/xxx.ets
  2. import { fileIo as fs, ReadOptions, WriteOptions } from '@kit.CoreFileKit';
  3. import { common } from '@kit.AbilityKit';
  4. // 获取应用文件路径
  5. let context = getContext(this) as common.UIAbilityContext;
  6. let filesDir = context.filesDir;
  7. function readWriteFile(): void {
  8.   // 打开文件
  9.   let srcFile = fs.openSync(filesDir + '/test.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  10.   let destFile = fs.openSync(filesDir + '/destFile.txt', fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  11.   // 读取源文件内容并写入至目的文件
  12.   let bufSize = 4096;
  13.   let readSize = 0;
  14.   let buf = new ArrayBuffer(bufSize);
  15.   let readOptions: ReadOptions = {
  16.     offset: readSize,
  17.     length: bufSize
  18.   };
  19.   let readLen = fs.readSync(srcFile.fd, buf, readOptions);
  20.   while (readLen > 0) {
  21.     readSize += readLen;
  22.     let writeOptions: WriteOptions = {
  23.       length: readLen
  24.     };
  25.     fs.writeSync(destFile.fd, buf, writeOptions);
  26.     readOptions.offset = readSize;
  27.     readLen = fs.readSync(srcFile.fd, buf, readOptions);
  28.   }
  29.   // 关闭文件
  30.   fs.closeSync(srcFile);
  31.   fs.closeSync(destFile);
  32. }
复制代码
说明
利用读写接口时,需留意可选项参数offset的设置。对于已存在且读写过的文件,文件偏移指针默认在前次读写操作的制止位置。
以流的情势读写文件

以下示例代码演示了如何利用流接口举行文件读写:

 
  1. // pages/xxx.ets
  2. import { fileIo as fs, ReadOptions } from '@kit.CoreFileKit';
  3. import { common } from '@kit.AbilityKit';
  4. // 获取应用文件路径
  5. let context = getContext(this) as common.UIAbilityContext;
  6. let filesDir = context.filesDir;
  7. async function readWriteFileWithStream(): Promise<void> {
  8.   // 打开文件流
  9.   let inputStream = fs.createStreamSync(filesDir + '/test.txt', 'r+');
  10.   let outputStream = fs.createStreamSync(filesDir + '/destFile.txt', "w+");
  11.   // 以流的形式读取源文件内容并写入目的文件
  12.   let bufSize = 4096;
  13.   let readSize = 0;
  14.   let buf = new ArrayBuffer(bufSize);
  15.   let readOptions: ReadOptions = {
  16.     offset: readSize,
  17.     length: bufSize
  18.   };
  19.   let readLen = await inputStream.read(buf, readOptions);
  20.   readSize += readLen;
  21.   while (readLen > 0) {
  22.     const writeBuf = readLen < bufSize ? buf.slice(0, readLen) : buf;
  23.     await outputStream.write(writeBuf);
  24.     readOptions.offset = readSize;
  25.     readLen = await inputStream.read(buf, readOptions);
  26.     readSize += readLen;
  27.   }
  28.   // 关闭文件流
  29.   inputStream.closeSync();
  30.   outputStream.closeSync();
  31. }
复制代码
说明
利用流接口时,需留意流的实时关闭。同时流的异步接口应严酷遵循异步接口利用规范,避免同步、异步接口混用。流接口不支持并发读写。

 
检察文件列表

以下示例代码演示了如何检察文件列表:

 
  1. import { fileIo as fs, Filter, ListFileOptions } from '@kit.CoreFileKit';
  2. import { common } from '@kit.AbilityKit';
  3. // 获取应用文件路径
  4. let context = getContext(this) as common.UIAbilityContext;
  5. let filesDir = context.filesDir;
  6. // 查看文件列表
  7. function getListFile(): void {
  8.   let listFileOption: ListFileOptions = {
  9.     recursion: false,
  10.     listNum: 0,
  11.     filter: {
  12.       suffix: [".png", ".jpg", ".txt"],
  13.       displayName: ["test*"],
  14.       fileSizeOver: 0,
  15.       lastModifiedAfter: new Date(0).getTime()
  16.     }
  17.   };
  18.   let files = fs.listFileSync(filesDir, listFileOption);
  19.   for (let i = 0; i < files.length; i++) {
  20.     console.info(`The name of file: ${files[i]}`);
  21.   }
  22. }
复制代码
利用文件流

以下实例代码演示了如何利用文件可读流,文件可写流

 
  1. // pages/xxx.ets
  2. import { fileIo as fs } from '@kit.CoreFileKit';
  3. import { common } from '@kit.AbilityKit';
  4. // 获取应用文件路径
  5. let context = getContext(this) as common.UIAbilityContext;
  6. let filesDir = context.filesDir;
  7. function copyFileWithReadable(): void {
  8.   // 创建文件可读流
  9.   const rs = fs.createReadStream(`${filesDir}/read.txt`);
  10.   // 创建文件可写流
  11.   const ws = fs.createWriteStream(`${filesDir}/write.txt`);
  12.   // 暂停模式拷贝文件
  13.   rs.on('readable', () => {
  14.     const data = rs.read();
  15.     if (!data) {
  16.       return;
  17.     }
  18.     ws.write(data);
  19.   });
  20. }
  21. function copyFileWithData(): void {
  22.   // 创建文件可读流
  23.   const rs = fs.createReadStream(`${filesDir}/read.txt`);
  24.   // 创建文件可写流
  25.   const ws = fs.createWriteStream(`${filesDir}/write.txt`);
  26.   // 流动模式拷贝文件
  27.   rs.on('data', (emitData) => {
  28.     const data = emitData?.data;
  29.     if (!data) {
  30.       return;
  31.     }
  32.     ws.write(data as Uint8Array);
  33.   });
  34. }
复制代码
以下代码演示了如何利用文件哈希流

 
  1. // pages/xxx.ets
  2. import { fileIo as fs } from '@kit.CoreFileKit';
  3. import { hash } from '@kit.CoreFileKit';
  4. import { common } from '@kit.AbilityKit';
  5. // 获取应用文件路径
  6. let context = getContext(this) as common.UIAbilityContext;
  7. let filesDir = context.filesDir;
  8. function hashFileWithStream() {
  9.   const filePath = `${filesDir}/test.txt`;
  10.   // 创建文件可读流
  11.   const rs = fs.createReadStream(filePath);
  12.   // 创建哈希流
  13.   const hs = hash.createHash('sha256');
  14.   rs.on('data', (emitData) => {
  15.     const data = emitData?.data;
  16.     hs.update(new Uint8Array(data?.split('').map((x: string) => x.charCodeAt(0))).buffer);
  17.   });
  18.   rs.on('close', async () => {
  19.     const hashResult = hs.digest();
  20.     const fileHash = await hash.hash(filePath, 'sha256');
  21.     console.info(`hashResult: ${hashResult}, fileHash: ${fileHash}`);
  22.   });
  23. }
复制代码
应用文件访问(C/C++)

 


场景介绍

FileIO模块提供了文件基础操作能力。
基本概念

结果集:满意利用场景精确的 URI。
束缚限定



  • 举行文件操作之前,必须保证传入精确有效的uri或path。
接口说明

接口的详细说明,请参考



API参考

 
接口名称形貌FileManagement_ErrCode OH_FileIO_GetFileLocation(char *uri, int uriLength, FileIO_FileLocation *location)获取文件存储位置。enum FileIO_FileLocation FileIO_FileLocation文件存储位置罗列值。enum enum FileManagement_ErrCode FileManagement_ErrCode文件管理模块错误码。 开发步骤

在CMake脚本中链接动态库

CMakeLists.txt中添加以下lib。

 
  1. target_link_libraries(sample PUBLIC libohfileio.so)
复制代码
添加头文件
 
  1. #include <filemanagement/fileio/oh_fileio.h>
复制代码
调用OH_FileIO_GetFileLocation接口获取文件存储位置。示例代码如下所示:

 
  1.     void GetFileLocationExample() {
  2.         char *uri = "file://com.example.demo/data/storage/el2/base/files/test.txt";
  3.         FileIO_FileLocation location;
  4.         FileManagement_ErrCode ret = OH_FileIO_GetFileLocation(uri, strlen(uri), &location);
  5.         if (ret == 0) {
  6.             if (location == FileIO_FileLocation::LOCAL) {
  7.                 printf("This file is on local.");
  8.             } else if (location == FileIO_FileLocation::CLOUD) {
  9.                 printf("This file is on cloud.");
  10.             } else if (location == FileIO_FileLocation::LOCAL_AND_CLOUD) {
  11.                 printf("This file is both on local and cloud.");
  12.             }
  13.         } else {
  14.             printf("GetFileLocation failed, error code is %d", ret);
  15.         }
  16.     }   
复制代码

应用及文件体系空间统计

 


在体系中,大概出现体系空间不够大概cacheDir等目录受体系配额限定等情况,需要应用开发者关注体系剩余空间,同时控制应用自身占用的空间大小。
接口说明

API的详细介绍请参见ohos.file.statvfs、ohos.file.storageStatistics。
表1 文件体系空间和应用空间统计
模块接口名功能@ohos.file.storageStatisticsgetCurrentBundleStats获取当前应用的存储空间大小(单位为Byte)。@ohos.file.statvfsgetFreeSize获取指定文件体系的剩余空间大小(单位为Byte)。@ohos.file.statvfsgetTotalSize获取指定文件体系的总空间大小(单位为Byte)。 表2 应用空间统计
BundleStats属性含义统计路径appSize应用安装文件大小(单位为Byte) 应用安装文件保存在以下目录:
/data/storage/el1/bundle
cacheSize应用缓存文件大小(单位为Byte) 应用的缓存文件保存在以下目录:
/data/storage/el1/base/cache
/data/storage/el1/base/haps/entry/cache
/data/storage/el2/base/cache
/data/storage/el2/base/haps/entry/cache
dataSize应用文件存储大小(除应用安装文件和缓存文件)(单位为Byte) 应用文件由本地文件、分布式文件以及数据库文件组成。
本地文件保存在以下目录(留意缓存文件目录为以下目录的子目录):
/data/storage/el1/base
/data/storage/el2/base
分布式文件保存在以下目录:
/data/storage/el2/distributedfiles
数据库文件保存在以下目录:
/data/storage/el1/database
/data/storage/el2/database
  开发示例



  • 获取文件体系数据分区剩余空间大小。

     
    1. import { statfs } from '@kit.CoreFileKit';
    2. import { BusinessError } from '@kit.BasicServicesKit';
    3. import { common } from '@kit.AbilityKit';
    4. let context = getContext(this) as common.UIAbilityContext;
    5. let path = context.filesDir;
    6. statfs.getFreeSize(path, (err: BusinessError, number: number) => {
    7.   if (err) {
    8.     console.error(`Invoke getFreeSize failed, code is ${err.code}, message is ${err.message}`);
    9.   } else {
    10.     console.info(`Invoke getFreeSize succeeded, size is ${number}`);
    11.   }
    12. });
    复制代码
    获取当前应用的存储空间大小。

     
    1. import { storageStatistics } from '@kit.CoreFileKit';
    2. import { BusinessError } from '@kit.BasicServicesKit';
    3. storageStatistics.getCurrentBundleStats((err: BusinessError, bundleStats: storageStatistics.BundleStats) => {
    4.   if (err) {
    5.     console.error(`Invoke getCurrentBundleStats failed, code is ${err.code}, message is ${err.message}`);
    6.   } else {
    7.     console.info(`Invoke getCurrentBundleStats succeeded, appsize is ${bundleStats.appSize}`);
    8.   }
    9. });
    复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

饭宝

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表