如何使用 nan 在 nodejs 中获取任意大小的缓冲区

How to get arbitrary sized buffers in nodejs using nan

我有一个节点 js 应用程序,它使用 sharp 对大文件进行一些图像处理,然后使用 nan 与节点进行交互。当我加载一个非常大的图像时,我从 nan 收到一个错误,上面写着

node: ../node_modules/nan/nan.h:679: Nan::MaybeLocal<v8::Object> Nan::NewBuffer(char*, size_t, node::Buffer::FreeCallback, void*): Assertion `length <= imp::kMaxLength && "too large buffer"' failed. Aborted (core dumped)

可以看到line 679 of nan.h here

但总而言之,它是这样说的:

// arbitrary buffer lengths requires // NODE_MODULE_VERSION >= IOJS_3_0_MODULE_VERSION assert(length <= imp::kMaxLength && "too large buffer");

我有

$ node -v v4.4.6

您在 top of the file 看到的应该是比 IOJS_3_0_MODULE_VERSION 更高的版本,提供任意长度的缓冲区。但是,断言没有被 #ifdef 包围。有谁知道在使用 nan 时如何使用任意长度的缓冲区?

NAN 维护者希望在所有节点版本中提供统一的行为,这似乎意味着坚持早期版本节点的限制 (discussion)。我想这就是为什么它周围没有 #ifdef 可以为新版本启用大缓冲区的原因。

如果您在不使用 NAN 的情况下为 Buffer 分配内存,那么您可以达到 0x7fffffff 的当前 kMaxLength(即超出 NAN 限制的额外千兆字节)。

size_t len = 0x7fffffff;
char* bigbuf = (char*)malloc(len);
node::Buffer::New(v8::Isolate::GetCurrent(), bigbuf, len);

我不确定您在您的管道中的哪个位置点击了它 - 是在您从磁盘读取时吗?其中一些技术可能有用:

  • 正在处理流中的数据。
  • 从 C++ 执行 I/O。
  • 正在逐块读取文件中的数据。 kMaxLength是最大索引,不是可以使用的最大内存量。因此,如果您可以从 C++ 或在流数据处理程序(使用 typedarray.set)中将大缓冲区读入更宽的 TypedArray,那么您可以 return 例如消耗 8,589,934,588 字节的 0x7fffffff-length Uint32Array。

    // Not tested
    var fs = require("fs");
    var path = "/path/to/file";
    var size = fs.statSync(path).size;
    var dest = new Uint32Array(size / Uint32Array.BYTES_PER_ELEMENT);
    var destOffset = 0;
    var rs = fs.createReadStream(path);
    rs.on("data", function (chunk) {
        var hunk = new Uint32Array(chunk.buffer, chunk.byteOffset, b.byteLength);
         dest.set(hunk, destOffset);
         destOffset += hunk.length;
    });