I read a file whose size is 32 bytes with fs.readFileSync.
I got a Buffer object whose length is 32, but the buffer property (which is an ArrayBuffer of the Buffer object) of the Buffer object has 8192 byteLength.
Code:
var fs = require('fs');
var buf = fs.readFileSync('/tmp/foo'); // foo's size is 32 bytes
console.log(buf.length); // 32
console.log(buf.buffer.byteLength); // 8192
This behavior might be confusing for someone who wants to use the buffer property of a Buffer object.
(I instantiated a typed array with buf.buffer, but the byteLength of the typed array was 8192, not 32.)
I guess this happens because readFileSync function returns a Buffer object allocated with Buffer.allocUnsafe in fs.js see line 530 in fs.js
(This may be related to a pre-allocated pool (8192 bytes) used in Buffer.allocUnsafe)
I suggest tryCreateBuffer in readFileSync to use Buffer.alloc instead of Buffer.allocUnsafe for creating a Buffer object.
Thanks.
This is not limited to readFileSync:
Buffer.from([ 0x0, 0x1, 0x2, 0x3 ]).buffer.byteLength == 8192
A buffer is a view onto an ArrayBuffer and does not necessarily correspond to the length of the buffer:
new Buffer(10).buffer.byteLength == 10
new Buffer(10).slice(0, 5).buffer.byteLength = 10
In general, there is no guarantee that buf.length and buf.buffer.byteLength are equal. I am not sure we consider this a bug. @nodejs/buffer @nodejs/fs
Not a bug, no. Node has worked this way ever since it had a Buffer type (the heady days of node.js v0.3.x; oh, to be young again) and it's a performance optimization.
Closing out as working-as-intended.
To clarify @bnoordhuis' somewhat laconic reply, this issue is in fact a duplicate of #11132. The buffer documentation contains a summary of interaction between Buffer, ArrayBuffer, and other TypedArray types.
Most helpful comment
Not a bug, no. Node has worked this way ever since it had a Buffer type (the heady days of node.js v0.3.x; oh, to be young again) and it's a performance optimization.
Closing out as working-as-intended.