HarmonyOS鸿蒙Next中fileIo Stream如何获取字节流中的大小

HarmonyOS鸿蒙Next中fileIo Stream如何获取字节流中的大小 我接收到一个字节流,在我不知道字节流大小的前提下应该如何读取字节流,我现在的做法是,创建了一个特别大的ArrayBuffer,然后将数据通过readSync写入buffer中,有没有别的方式呢,比如一次读取多少个字节,读取到结束为止,我怕字节流大小超出了我的ArrayBuffer大小,会导致dump。具体代码如下:

let fsStream = fileIo.fdopenStreamSync(fd,"r+");
let buffer = new ArrayBuffer(50*1024*1024);
let num = fsStream.readSync(buffer);
console.log(`扫描后图像数据长度为${num}`);
let bufferRead = buffer.slice(0,num);
fsStream.closeSync();

更多关于HarmonyOS鸿蒙Next中fileIo Stream如何获取字节流中的大小的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

可以尝试下循环读取至流结束

通过判断 read 方法的返回值是否为0,确认是否读取完毕:

代码仅供参考

import fs from '@kit.FileKit';

let totalBytes = 0;
let chunks = [];
let readOptions = { offset: 0 };  // 设置读取偏移量

// 打开文件流
let file = fs.openSync(filePath, fs.OpenMode.READ_ONLY);
let fsStream = fs.fdopenStreamSync(file.fd, "r");

// 循环读取数据块
let readLen: number;
do {
  readLen = await fsStream.read(buffer, readOptions);
  if (readLen > 0) {
    chunks.push(buffer.slice(0, readLen));
    totalBytes += readLen;
    readOptions.offset += readLen;  // 更新偏移量
  }
} while (readLen > 0);

fsStream.closeSync();

若需要完整数据,可将分块数据拼接为Uint8Array:

let mergedBuffer = new Uint8Array(totalBytes);
let offset = 0;
for (let chunk of chunks) {
  mergedBuffer.set(new Uint8Array(chunk), offset);
  offset += chunk.byteLength;
}

更多关于HarmonyOS鸿蒙Next中fileIo Stream如何获取字节流中的大小的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


官网demo:

// pages/xxx.ets
import { fileIo as fs, ReadOptions } from '@kit.CoreFileKit';
import { common } from '@kit.AbilityKit';

// 获取应用文件路径
let context = getContext(this) as common.UIAbilityContext;
let filesDir = context.filesDir;

async function readWriteFileWithStream(): Promise<void> {
  // 创建并打开输入文件流
  let inputStream = fs.createStreamSync(filesDir + '/test.txt', 'r+');
  // 创建并打开输出文件流
  let outputStream = fs.createStreamSync(filesDir + '/destFile.txt', "w+");

  let bufSize = 4096;
  let readSize = 0;
  let buf = new ArrayBuffer(bufSize);
  let readOptions: ReadOptions = {
    offset: readSize,
    length: bufSize
  };
  // 以流的形式读取源文件内容并写入到目标文件
  let readLen = await inputStream.read(buf, readOptions);
  readSize += readLen;
  while (readLen > 0) {
    const writeBuf = readLen < bufSize ? buf.slice(0, readLen) : buf;
    await outputStream.write(writeBuf);
    readOptions.offset = readSize;
    readLen = await inputStream.read(buf, readOptions);
    readSize += readLen;
  }
  // 关闭文件流
  inputStream.closeSync();
  outputStream.closeSync();
}

http协议响应头 Content-Length 字段

我不是从http传过来的,没有长度相关的内容。只有字节流,

在HarmonyOS鸿蒙Next中,使用fileIo模块的Stream对象处理字节流时,可通过stream.bytesAvailable属性直接获取当前可读取的字节数。该属性返回的是缓冲区中未读取的字节数量,适用于实时获取流数据大小。若需总大小,通常需结合文件元数据操作。

在HarmonyOS Next中,可以通过循环读取的方式动态处理未知大小的字节流,避免一次性分配过大内存。建议使用以下方法:

let fsStream = fileIo.fdopenStreamSync(fd, "r+");
let chunks = [];
let totalBytes = 0;
const CHUNK_SIZE = 8192; // 8KB缓冲区

while (true) {
    let buffer = new ArrayBuffer(CHUNK_SIZE);
    let bytesRead = fsStream.readSync(buffer);
    
    if (bytesRead <= 0) break;
    
    chunks.push(buffer.slice(0, bytesRead));
    totalBytes += bytesRead;
}

fsStream.closeSync();

// 合并所有数据块
let finalBuffer = new ArrayBuffer(totalBytes);
let offset = 0;
chunks.forEach(chunk => {
    new Uint8Array(finalBuffer).set(new Uint8Array(chunk), offset);
    offset += chunk.byteLength;
});

这种方式通过分块读取,动态收集数据片段,最后合并成完整缓冲区,既避免了内存溢出风险,又能准确获取流数据的总大小。

回到顶部