# @exodus/buffer-layout 中文文档

规范地址：https://npmcn.com/package/%40exodus/buffer-layout/

版本：1\.2\.2-exodus\.0
npm 元数据更新时间：2026-10-06T20:58:44.764Z
中文译文更新时间：2026-11-14T03:51:50.067Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40exodus/buffer-layout
原文对照：https://npmcn.com/package/%40exodus/buffer-layout/?lang=original
项目主页：https://github.com/pabigot/buffer-layout
源码仓库：https://github.com/pabigot/buffer-layout

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：107 kB，5 个文件
- 模块格式：CommonJS
- TypeScript 类型：未声明
- Node.js 要求：\>=4\.5
- 运行依赖：0 个
- 首次发布：2020-11-05T17:39:22.068Z
- 最新版本发布：2022-03-22T17:13:06.751Z
- 近 30 天下载量：45318（2026-10-14 至 2026-11-12，npm 官方下载统计）
- 已发布版本数：3（近 12 个月 0 个）

## 中文简介

JavaScript 值和缓冲之间的翻译

## 安装

```sh
npm install @exodus/buffer-layout
```

也可以使用：`pnpm add @exodus/buffer-layout`、`yarn add @exodus/buffer-layout`、`bun add @exodus/buffer-layout`

## README

# 缓冲放出

[![NPM version](https://img.shields.io/npm/v/buffer-layout.svg)](https://www.npmjs.com/package/buffer-layout "View this project on NPM") [![Build Status](https://travis-ci.org/pabigot/buffer-layout.svg?branch=master)](https://travis-ci.org/pabigot/buffer-layout "Check build status on TravisCI") [![Coverage Status](https://coveralls.io/repos/pabigot/buffer-layout/badge.svg?branch=master&service=github)](https://coveralls.io/github/pabigot/buffer-layout?branch=master "Check coverage status on Coveralls")

缓冲放出是纯 JavaScript 中执行的一个工具模块 支持JavaScript值和缓冲器之间的翻译。 已经做了 可通过 [gi](https://github.com/pabigot/buffer-layout) 财务报告和审定财务报表 以麻省理工学院的许可释放.

为这类数据提供版式支持:

-   长度为 1至 6 字节的已签名和未签名的整体值 little-endian 或 big-endian 格式;
-   已签名和未签名的64位集成值已解码为集成 数字;
-   浮出值和双相值(也叫小-endian或大-endian);
-   任意布局、恒定或 数据依赖长度;
-   含有任意布局的指定字段的结构;
-   将数据类型记录在 前缀值,另一个布局元素,或外部提供;
-   8, 16, 24, 或32位无符号整数的位字段, 编号 最低或最重大部分;
-   NUL 终止的 C 字符串;
-   固定或可变长原始数据组.

## 安装

开发和测试使用Node.js,支持版本4.5 及后会. 安装方式 `npm install buffer-layout`。 。 。 .

## 实例

所有例子来自 `test/examples.js` 单位测试并假设 以下语境:

```
const assert = require('assert');
const util = require('util');
const lo = require('buffer-layout');
```

例子只说明了可以做些什么。 结构、工会、, 和序列可以筑巢; [工会 歧视者](http://pabigot.github.io/buffer-layout/module-Layout-UnionDiscriminator.html) 可以是工会内部的,也可以是工会外部的; 序列和短长可能 从缓冲器中固定或读取.

详细情况见 [文档](http://pabigot.github.io/buffer-layout/)。 。 。 .

### 16 位签名小端整数的四元素阵列

C的定义:

```
int16_t arr[4] = { 1, -1, 3, -3 };
```

缓冲出道:

```
const ds = lo.seq(lo.s16(), 4);
const b = Buffer.alloc(8);
assert.equal(ds.encode([1, -1, 3, -3], b), 4 * 2);
assert.equal(Buffer.from('0100ffff0300fdff', 'hex').compare(b), 0);
assert.deepEqual(ds.decode(b), [1, -1, 3, -3]);
```

见 [内](http://pabigot.github.io/buffer-layout/module-Layout-Int.html) 财务报告和审定财务报表 [顺序](http://pabigot.github.io/buffer-layout/module-Layout-Sequence.html)。 。 。 .

### 一个本地 C `struct` 搭乘32位小号的机器

C的定义:

```
struct ds {
  uint8_t v;
  uint32_t u32;
} st;
```

缓冲出道:

```
const ds = lo.struct([lo.u8('v'),
                    lo.seq(lo.u8(), 3), // alignment padding
                    lo.u32('u32')]);
assert.equal(ds.offsetOf('u32'), 4);
const b = Buffer.alloc(8);
b.fill(0xbd);
assert.equal(ds.encode({v: 1, u32: 0x12345678}, b), 1 + 3 + 4);
assert.equal(Buffer.from('01bdbdbd78563412', 'hex').compare(b), 0);
assert.deepEqual(ds.decode(b), {v: 1, u32: 0x12345678});
```

注意,C语言要求必须明确添加的文字 在缓冲放出结构定义中。 因为垫子不是 可访问,相应的布局没有 [属性](http://pabigot.github.io/buffer-layout/module-Layout-Layout.html#property)。 。 。 .

见 [结构](http://pabigot.github.io/buffer-layout/module-Layout-Structure.html)。 。 。 .

### 包装 C `struct` 搭乘32位小号的机器

C的定义:

```
struct ds {
  uint8_t v;
  uint32_t u32;
} __attribute__((__packed__)) st;
```

缓冲出道:

```
const ds = lo.struct([lo.u8('v'),
                    lo.u32('u32')]);
assert.equal(ds.offsetOf('u32'), 1);
const b = Buffer.alloc(5);
b.fill(0xbd);
assert.equal(ds.encode({v: 1, u32: 0x12345678}, b), 1 + 4);
assert.equal(Buffer.from('0178563412', 'hex').compare(b), 0);
assert.deepEqual(ds.decode(b), {v: 1, u32: 0x12345678});
```

### 标记为 4 字节值的结合

假设一个5字节的组合结构,其中解释最后一个 4个字节取决于第一个字节. C的定义:

```
struct {
  uint8_t t;
  union ds {
    uint8_t u8[4];  // default interpretation
    int16_t s16[2]; // when t is 'h'
    uint32_t u32;   // when t is 'w'
    float f32;      // when t is 'f'
  } u;
} __attribute__((__packed__)) un;
```

缓冲出道:

```
const t = lo.u8('t');
const un = lo.union(t, lo.seq(lo.u8(), 4, 'u8'));
const nul = un.addVariant('n'.charCodeAt(0), 'nul');
const u32 = un.addVariant('w'.charCodeAt(0), lo.u32(), 'u32');
const s16 = un.addVariant('h'.charCodeAt(0), lo.seq(lo.s16(), 2), 's16');
const f32 = un.addVariant('f'.charCodeAt(0), lo.f32(), 'f32');
const b = Buffer.alloc(un.span);
assert.deepEqual(un.decode(b), {t: 0, u8: [0, 0, 0, 0]});
assert.deepEqual(un.decode(Buffer.from('6e01020304', 'hex')),
                 {nul: true});
assert.deepEqual(un.decode(Buffer.from('7778563412', 'hex')),
                 {u32: 0x12345678});
assert.deepEqual(un.decode(Buffer.from('660000bd41', 'hex')),
                 {f32: 23.625});
assert.deepEqual(un.decode(Buffer.from('a5a5a5a5a5', 'hex')),
                 {t: 0xa5, u8: [0xa5, 0xa5, 0xa5, 0xa5]});
assert.equal(s16.encode({s16: [123, -123]}, b), 1 + 2 * 2);
assert.equal(Buffer.from('687b0085ff', 'hex').compare(b), 0);
```

见 [工会](http://pabigot.github.io/buffer-layout/module-Layout-Union.html)。 。 。 .

### 在小endian 机器上包装了位字段

C的定义:

```
struct ds {
  unsigned int b00l03: 3;
  unsigned int flg03: 1;
  unsigned int b04l18: 24;
  unsigned int b1Cl04: 4;
} st;
```

缓冲出道:

```
const ds = lo.bits(lo.u32());
const b = Buffer.alloc(4);
ds.addField(3, 'b00l03');
ds.addBoolean('flg03');
ds.addField(24, 'b04l18');
ds.addField(4, 'b1Cl04');
b.fill(0xff);
assert.equal(ds.encode({b00l03: 3, b04l18: 24, b1Cl04: 4}, b), 4);
assert.equal(Buffer.from('8b010040', 'hex').compare(b), 0);
assert.deepEqual(ds.decode(b),
                 {b00l03: 3, flg03: true, b04l18: 24, b1Cl04: 4});
```

见 [位图](http://pabigot.github.io/buffer-layout/module-Layout-BitStructure.html)。 。 。 .

### 64- 位值作为数字

C的定义:

```
uint64_t v = 0x0102030405060708ULL;
```

缓冲出道:

```
const ds = lo.nu64be();
const b = Buffer.from('0102030405060708', 'hex');
const v = 72623859790382856;
const nv = v - 6;
assert.equal(v, nv);
assert.equal(ds.decode(b), nv);
```

注意,由于精确值不低于2^53,因此不能是 以 JavaScript 编号表示,取而代之的是近似于 附近的可代表整数,在数字中等同.

见 [近Uint64号](http://pabigot.github.io/buffer-layout/module-Layout-NearUInt64.html)。 。 。 .

### NUL 终止的 C 字符串

C的定义:

```
const char str[] = "hi!";
```

缓冲出道:

```
const ds = lo.cstr();
const b = Buffer.alloc(8);
assert.equal(ds.encode('hi!', b), 3 + 1);
const slen = ds.getSpan(b);
assert.equal(slen, 4);
assert.equal(Buffer.from('68692100', 'hex').compare(b.slice(0, slen)), 0);
assert.equal(ds.decode(b), 'hi!');
```

见 [结晶](http://pabigot.github.io/buffer-layout/module-Layout-CString.html)。 。 。 .

### 在缓冲区内抵消的固定长数据区块

缓冲出道:

```
const ds = lo.blob(4);
const b = Buffer.from('0102030405060708', 'hex');
assert.equal(Buffer.from('03040506', 'hex').compare(ds.decode(b, 2)), 0);
```

见 [块](http://pabigot.github.io/buffer-layout/module-Layout-Blob.html)。 。 。 .

### C字符串的可变长阵列

缓冲出道:

```
const pr = lo.seq(lo.cstr(), 2);
const n = lo.u8('n');
const vla = lo.seq(pr, lo.offset(n, -1), 'a');
const st = lo.struct([n, vla], 'st');
const b = Buffer.alloc(32);
const arr = [['k1', 'v1'], ['k2', 'v2'], ['k3', 'etc']];
b.fill(0);
assert.equal(st.encode({a: arr}, b),
             1 + (2 * ((2 + 1) + (2 + 1)) + (2 + 1) + (3 + 1)));
const span = st.getSpan(b);
assert.equal(span, 20);
assert.equal(Buffer.from('036b31007631006b32007632006b330065746300', 'hex')
             .compare(b.slice(0, span)), 0);
assert.deepEqual(st.decode(b), {n: 3, a: arr});
```

见 [偏移拉约特](http://pabigot.github.io/buffer-layout/module-Layout-OffsetLayout.html)。 。 。 .

### 带有隐形长度的 C 灵活阵列成员

当通过包式接口获取数据时 包可以提供最后一个字段的隐含限制.

C的定义:

```
struct ds {
  uint8_t prop;
  uint16_t data[];
};
```

缓冲出道:

```
const st = lo.struct([lo.u8('prop'),
                    lo.seq(lo.u16(),
                           lo.greedy(lo.u16().span),
                           'data')],
                   'ds');
const b = Buffer.from('21010002030405', 'hex');
assert.deepEqual(st.decode(b), {prop: 33, data: [0x0001, 0x0302, 0x0504]});
b.fill(0xFF);
assert.equal(st.encode({prop: 9, data: [5, 6]}, b), 1 + 2 * 2);
assert.equal(Buffer.from('0905000600FFFF', 'hex').compare(b), 0);
```

### 标记值或可变长度结合

使用主字节存储任意数据以识别内容 这种价值只占用必要的空间.

该实例还显示如何将变体识别API扩展至 支持任意常数,而不消耗其空间 密码结合。 这可以用来制造类似 [贝森](http://bsonspec.org/spec.html)。 。 。 .

以下是定义结合的代码,变体,以及 承认 `true` 财务报告和审定财务报表 `false` 数值 `b` 作为不同的变体:

```
const un = lo.union(lo.u8('t'));
const u8 = un.addVariant('B'.charCodeAt(0), lo.u8(), 'u8');
const s16 = un.addVariant('h'.charCodeAt(0), lo.s16(), 's16');
const s48 = un.addVariant('Q'.charCodeAt(0), lo.s48(), 's48');
const cstr = un.addVariant('s'.charCodeAt(0), lo.cstr(), 'str');
const tr = un.addVariant('T'.charCodeAt(0), lo.const(true), 'b');
const fa = un.addVariant('F'.charCodeAt(0), lo.const(false), 'b');
const b = Buffer.alloc(1 + 6);
un.configGetSourceVariant(function(src) {
  if (src.hasOwnProperty('b')) {
    return src.b ? tr : fa;
  }
  return this.defaultGetSourceVariant(src);
});
```

这里有编码的例子 检查编码的长度 解码每个选项:

```
b.fill(0xff);
assert.equal(un.encode({u8: 1}, b), 1 + 1);
assert.equal(un.getSpan(b), 2);
assert.equal(Buffer.from('4201ffffffffff', 'hex').compare(b), 0);
assert.equal(un.decode(b).u8, 1);

b.fill(0xff);
assert.equal(un.encode({s16: -32000}, b), 1 + 2);
assert.equal(un.getSpan(b), 3);
assert.equal(Buffer.from('680083ffffffff', 'hex').compare(b), 0);
assert.equal(un.decode(b).s16, -32000);

b.fill(0xff);
const v48 = Math.pow(2, 47) - 1;
assert.equal(un.encode({s48: v48}, b), 1 + 6);
assert.equal(un.getSpan(b), 7);
assert.equal(Buffer.from('51ffffffffff7f', 'hex').compare(b), 0);
assert.equal(un.decode(b).s48, v48);

b.fill(0xff);
assert.equal(un.encode({b: true}, b), 1);
assert.equal(un.getSpan(b), 1);
assert.equal(Buffer.from('54ffffffffffff', 'hex').compare(b), 0);
assert.strictEqual(un.decode(b).b, true);

b.fill(0xff);
assert.equal(un.encode({b: false}, b), 1);
assert.equal(un.getSpan(b), 1);
assert.equal(Buffer.from('46ffffffffffff', 'hex').compare(b), 0);
assert.strictEqual(un.decode(b).b, false);
```

**页:1** 这个密码很长的 [错误进入 Buffer. write Int{L,B} E 缓冲键](https://github.com/nodejs/node/pull/3994); 如果你们 在4.2.4或5.2.0之前正在使用节点,您应当更新.

## 常见问题

### @exodus/buffer-layout 是什么？

JavaScript 值和缓冲之间的翻译

### 如何安装 @exodus/buffer-layout？

在项目目录运行 npm install @exodus/buffer-layout，或使用 pnpm add / yarn add / bun add。

### @exodus/buffer-layout 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/exodus\_\_buffer-layout 是否存在。

### @exodus/buffer-layout 支持 ESM 还是 CommonJS？

以 CommonJS 形式发布，可以直接 require\(\)；在 ES Module 项目中也可以用 import 引入（Node\.js 会把 module\.exports 作为默认导出）。

### @exodus/buffer-layout 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=4\.5。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @exodus/buffer-layout 可以商用吗？

@exodus/buffer-layout 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @exodus/buffer-layout 的下载量有多少？

根据 npm 官方下载统计，@exodus/buffer-layout 在 2026/10/14 – 2026/11/12 这 30 天内被下载 45,318 次，日均约 1,511 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @exodus/buffer-layout 还在维护吗？

最新版本 1\.2\.2-exodus\.0 发布于 2022/03/23（4 年前）；至今共发布 3 个版本，其中过去 12 个月发布了 0 个；首次发布于 2020/11/06。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

