如果您读取的文件小于8KB,大小为NodeJS allocates 8 KB for it.

这不是直观的,也不是预期的,我们得到的字节比我们投入的要多.但它也不是一个bug,至少在它被记录的意义上是这样.

Minimal NodeJS Example

const { Buffer } = require("node:buffer");

// Create a buffer smaller than `Buffer.poolSize`.
const nodeBuffer = Buffer.from(new Uint8Array([0, 1, 2, 3, 4]));

// size is 8KB, not 5 bytes.
console.log(nodeBuffer.buffer);

Question

  • 为什么8KB的缓冲区大小比我们期望的缓冲区大小(文件中数据的大小)更好??

超过8KB的文件将有一个与文件中字节数匹配的分配空间.

Other Details

我知道我们可以使用偏移量来阅读:

// 1 KB
const buffer = fs.readFileSync(fileName, buffer.byteOffset, buffer.byteLength)

但问题不是这个.

推荐答案

线索就在你链接的房产的名字里,poolSize.

Elsewhere on the same page:

Buffer模块预分配一个大小为Buffer.poolSize的内部Buffer实例,该实例用作池,用于快速分配使用Buffer.allocUnsafe()Buffer.from(array)Buffer.concat()创建的新Buffer实例,仅当大小小于Buffer.poolSize >>> 1时(Buffer.poolSize的下限除以2).

换句话说,这是出于性能原因,因为分配和释放内存可能会很慢;相反,模块会使用内存池来进行适当的较小分配.如果您想要一个更小的缓冲区,从池外分配它可能仍然比拥有一个稍大于您所需的缓冲区的效率要低.

(在 compose 本文时)你可以使用buf.buffer and buf.byteOffset properties来看到两个小的分配确实是在同一个ArrayBuffer上完成的:

> const { Buffer } = require("node:buffer");
> a = Buffer.from([1,2,3,4])
<Buffer 01 02 03 04>
> a.buffer
ArrayBuffer {
  [Uint8Contents]: <2f 00 00 00 00 00 00 00 01 02 03 04 00 00 00 00 00 00 00 00 00 ...>,
  byteLength: 8192
}
> b = Buffer.from([5,6,7,8])
<Buffer 05 06 07 08>

> b.buffer
ArrayBuffer {
  [Uint8Contents]: <2f 00 00 00 00 00 00 00 01 02 03 04 00 00 00 00 05 06 07 08 00 ...>,
  byteLength: 8192
}
> a.byteOffset
8
> b.byteOffset
16
>

Node.js相关问答推荐

使用HTTPS从NodeJS 17.9.1升级到18.0.0后,SignalR连接失败

如何更改ejs中的镜像src,以防从OMDB API获取的某些镜像具有src=N/A

如何在MEVN堆栈中结合创建和更新表单流程?

控制台显示一个长对象,我可以';每当我发布更新Mongoose数据库的请求时,我都不知道错误是什么,

使用AWS SDK for JavaScript V3将图像从node.js上传到s3 bucket

Mongoose:如何使用填充进行查找

Nestjs重写子类dto nodejs中的属性

表达 js 错误处理程序在第一个之后被忽略

使用react 组件加载特定 DIV 而无需重新加载整个页面

Axios GET 返回不可读的响应

是Electron 的密码和登录凭据的安全存储吗?

aws cdk 2.0 init 应用程序无法构建更漂亮的问题,这来自 jest-snapshot

mongoose 模式中的嵌套对象

在 Node.js 中的两个不同进程之间进行通信

如何将子集合添加到 Firestore 中的文档?

通过 POST 请求将数据从 node.js 服务器发送到 node.js 服务器

如何使用 Node.js、Express 和 Mongoose 进行身份验证?

chart.js 无法创建图表:无法从给定项目获取上下文

如何从 Node.js 中的 URL 获取

Meteor - collection.find() 总是返回所有字段