最终方案:
async readBytes(length: number = 1): Promise<Buffer> {
return new Promise<Buffer>((resolve) => {
this.reader.on('readable', () => {
// 读取指定长度的字节
let readedBuffer = this.reader.read(length)
if (readedBuffer == null) {
logd(`[readBytes] readedBuffer is null, stream buffer is empty`)
return
}
// 可能返回string,转换成Buffer
if (!Buffer.isBuffer(readedBuffer)) {
readedBuffer = Buffer.from(readedBuffer)
}
// 移除监听器
this.reader.removeAllListeners('readable')
resolve(readedBuffer)
})
})
}
1
yaodong0126 2023-07-26 15:40:17 +08:00
感觉是你使用上出现了问题,既然使用了 stream ,一般来说是不需要自己控制数据的读取的,通过 pipe 处理就好了,即使使用三方库也是同样的逻辑
|
2
yaodong0126 2023-07-26 15:43:29 +08:00
举个例子
const { createReadStream, createWriteStream } = require('fs') const readStream = createReadStream('/foo') const writeStream = createWriteStream('/bar') readStream.pipe(writeStream) |
3
xlsepiphone OP @yaodong0126 #2 我只是想按照字节读取,主要是解析二进制数据。看来还是只有自己创建缓冲区,多读几次。
|
4
yaodong0126 2023-07-26 15:55:46 +08:00 1
@xlsepiphone 如果需要这么做的,这属于 stream 的第二种使用方式,可以参考: https://nodejs.org/dist/latest-v20.x/docs/api/stream.html#two-reading-modes
|
5
xlsepiphone OP 更新了下代码,已结解决了:
```typescript readBytes(length: number = 1): Buffer { // 按照指定长度创建缓冲区 let buffer: Buffer = Buffer.alloc(length) // 已经读取的字节长度 let readedLength = 0 for (;;) { // 如果已经读取的字节长度等于指定的长度,则退出循环 if (readedLength === length) { break } // 计算出可以读取的字节长度 const readableLength = Math.min(length - readedLength, this.reader.readableLength) // 读取指定长度的字节 const readedBuffer = this.reader.read(readableLength) // 填充到缓冲区中 buffer.fill(readedBuffer, readedLength) // 更新已经读取的字节长度 readedLength += readableLength } return buffer } ``` |