前言

对于大文件读写,流式操作比一次性读写更高效,避免内存溢出。@pura/harmony-utilsFileUtil 封装了文件流操作方法,支持按需读写文件内容。本文将从API说明、代码实战、进阶用法、常见问题等多个维度进行全面讲解,帮助开发者快速掌握并应用到实际项目中。

在这里插入图片描述

一、FileUtil流操作核心API

FileUtil 提供了以下文件流操作方法:

方法 说明 返回类型 使用场景
createReadStream(path) 创建读取流 Stream 大文件读取
createWriteStream(path) 创建写入流 Stream 大文件写入
readBytes(stream, length) 读取指定字节 ArrayBuffer 分批读取
writeBytes(stream, buffer) 写入字节 void 分批写入

1.1 核心特性

  • 简洁易用:封装复杂API为一行调用,降低使用门槛
  • 类型安全:完整的TypeScript类型定义,编译期即可发现错误
  • 异常处理:内置异常捕获机制,避免运行时崩溃
  • 内存友好:流式操作避免一次性加载大文件到内存

1.2 流式操作与一次性操作对比

特性 流式操作 一次性操作
内存占用
适用文件大小 大文件 小文件
操作复杂度 较高 较低
代码量 较多 较少

二、完整使用步骤

2.1 安装依赖

ohpm install @pura/harmony-utils

2.2 流式读取

import { FileUtil } from '@pura/harmony-utils';

Button('流式读取文件')
  .width('100%')
  .onClick(() => {
    try {
      let path = FileUtil.getFilesDir() + '/large.dat';
      let stream = FileUtil.createReadStream(path);
      this.result = '读取流创建成功 ✅\n可按需读取文件内容';
    } catch (e) {
      this.result = '异常: ' + e;
    }
  })

2.3 流式写入

Button('流式写入文件')
  .width('100%')
  .onClick(() => {
    try {
      let path = FileUtil.getFilesDir() + '/output.dat';
      let stream = FileUtil.createWriteStream(path);
      this.result = '写入流创建成功 ✅\n可分批写入数据';
    } catch (e) {
      this.result = '异常: ' + e;
    }
  })

在这里插入图片描述

三、完整页面示例

import { FileUtil } from '@pura/harmony-utils';

@Entry
@Component
struct FileStreamDemo {
  @State result: string = '';

  build() {
    Column({ space: 12 }) {
      Button('流式操作').width('100%').onClick(() => {
        try {
          this.result = '流式操作适用于大文件\n避免一次性加载到内存';
        } catch (e) { this.result = '异常: ' + e; }
      });
      Text(this.result).fontSize(14).fontColor('#333333')
    }
    .padding(16)
  }
}

四、进阶用法

4.1 分批读取大文件

import { FileUtil } from '@pura/harmony-utils';

async function readLargeFile(path: string, chunkSize: number): void {
  let stream = FileUtil.createReadStream(path);
  let offset = 0;
  while (true) {
    let chunk = FileUtil.readBytes(stream, chunkSize);
    if (chunk.byteLength === 0) break;
    processChunk(chunk);
    offset += chunk.byteLength;
  }
}

4.2 流式文件拷贝

function streamCopy(src: string, dest: string, chunkSize: number = 4096): void {
  let readStream = FileUtil.createReadStream(src);
  let writeStream = FileUtil.createWriteStream(dest);
  while (true) {
    let chunk = FileUtil.readBytes(readStream, chunkSize);
    if (chunk.byteLength === 0) break;
    FileUtil.writeBytes(writeStream, chunk);
  }
}

五、注意事项

  1. 流关闭:使用完毕后务必关闭流,释放系统资源
  2. 缓冲区大小:合理设置每次读写的缓冲区大小
  3. 异常处理:流操作中需处理可能的IO异常
  4. 初始化依赖:使用前需确保 AppUtil.init() 已调用
  5. 并发安全:同一文件不要同时打开多个流

六、常见问题

Q1: 流式操作比一次性操作慢?

流式操作有额外开销,小文件建议使用一次性操作,大文件才使用流式操作。

Q2: 如何确定合适的缓冲区大小?

一般建议4KB-64KB,具体取决于文件大小和内存情况。

Q3: 流操作中断后如何恢复?

需要记录已处理的偏移量,重新打开流后从断点继续。

Q4: 流式操作支持网络文件吗?

FileUtil 的流操作仅支持本地文件,网络文件需先下载到本地。

在这里插入图片描述

总结

FileUtil 的文件流操作方法为大文件处理提供了内存友好的解决方案。本文详细介绍了核心API、使用步骤、完整示例、进阶用法以及常见问题的解决方案。开发者应根据文件大小选择合适的读写方式。

本文基于 @pura/harmony-utils 工具库,更多功能请参考官方文档与后续系列文章。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐