Buffer.byteLength 返回截然不同的字节长度

Buffer.byteLength returning drastically different byte length

本文关键字:字节 截然不同 byteLength 返回 Buffer      更新时间:2023-09-26

使用 Node.js v5.1.0,我正在尝试确定缓冲区的内容长度。因此,我正在这样做:

Buffer.byteLength(self.data, 'utf8')

self.data看起来像这样:

<Buffer ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 f0 00 f0 00 00 ff db 00 43 00 05 03 04 04 04 03 05 04 04 04 05 05 05 06 07 0c 08 07 07 07 07 0f 0b 0b 09 ... >

我正在加载的图像在文件系统 (OS X( 上为 109,055 字节(磁盘上为 111 KB(,但我的内容长度计算返回 198,147 字节。如果我将编码设置为 ascii ,它将返回 104,793 字节。更近了,但仍然不正确。

我计算正确吗?我是否需要对缓冲区执行某些操作才能使其返回正确的值?如果我做得对,为什么会有这种差异?如果我做错了,好吧,请分享;)

我认为差异如下:(编辑:根据此评论,似乎下面的一些解释是不正确的;等待更正的描述/摘要(

  • buffer.length:缓冲区的已用长度+保留长度。
  • buffer.byteLength:缓冲区的已用长度。
  • buffer.toString((.length:缓冲区字节的默认字符串呈现/解释中的字符数。您可以通过提供不同的编码来更改该呈现/集成。(例如。 toString("ascii") (
  • Buffer.byteLength(buffer, targetEncoding(:理解"buffer"中的字节使用UTF-8编码(即字节旨在呈现/解释为UTF-8字符串(,这将返回以某种指定编码(targetEncoding(存储该UTF-8字符串所需的字节数。

关于最后一项(Buffer.byteLength()(,我不完全确定我的解释是否正确,但这是我从这里的简要描述中得出的最好的结果:https://nodejs.org/api/buffer.html#buffer_class_method_buffer_bytelength_string_encoding

编辑:根据此评论,上面的描述对于buffer.lengthbuffer.byteLength之一似乎不正确(因为他们有一个缓冲区,其byteLength高于其length(。如果有人发现不匹配的解释,请评论或编辑此帖子!

如文档中所述,Buffer.byteLength() 返回假定特定编码的字符串的字节长度。

Buffer类型实际上是一个ArrayBuffer这意味着它的长度可以通过byteLength属性获取。此外,Node 的实现还添加了一个提供相同长度的 length 属性。

OP 中的混淆在于 Buffer.byteLength() 函数,该函数将字符串和编码作为参数,与缓冲区对象上的 .byteLength 属性不同。

投票最高的答案也混淆了这两个概念(Buffer.byteLength 返回截然不同的字节长度(,但我无法再改变我对它的投票。

以下是解释:

let buf = Buffer.alloc(4); // <Buffer 00 00 00 00>
buf.length; // 4
buf.byteLength; // 4
buf.byteLength === buf.Length //true

此时我们知道,作为缓冲区对象的属性.byteLength.length是严格相等的。

buf.write('ab'); // 2 - returns length of string 'ab' written to buf
buf.length // 4
buf.byteLength // 4

.length . 和 .byteLength 都返回 4。正如链接答案所声称的那样,保留长度和使用长度之间没有区别。

关于 Buffer.byteLength(string, encoding='utf-8') 函数(不同于 .byteLength 属性(,可接受的答案是正确的,该函数给出了使用指定编码参数(默认 utf-8(编码的字符串的字节长度。

// Function to convert a base64 'data:...ssdd//' data Uri to arrayBuffer
function base64tobuffer(base64) {
  return new Promise((resolve) => {
    fetch(base64).then((response) => {return(response.arrayBuffer())})
      .then((b)=>{
        if(b.byteLength % 2 == 0) {
            //console.log("The number is even.");
        }else{console.log(`The number ${b.byteLength} is odd`);b = b.slice(0,b.byteLength-1)}
        resolve(b);
    });
  })
}

我需要一个缓冲器,byteLength

b = b.slice(0,b.byteLength-1)

或者使用时导致错误

new Uint16Array(buffer);

稍后在我的项目中。上面的代码片最后byteLength,不会干扰缓冲区的标头