0

我有一个 node js 应用程序,它使用sharp对大文件进行一些图像处理,然后使用 nan 与 node.js 交互。当我加载一个非常大的图像时,我从 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)

你可以在这里看到 nan.h 的第 679 行

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

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

我有

$ node -v v4.4.6

您可以看到文件顶部的哪个版本应该是比 更高的版本IOJS_3_0_MODULE_VERSION,提供任意长度的缓冲区。但是,断言没有被 s 包围#ifdef。有谁知道在使用 nan 时如何使用任意长度的缓冲区?

4

1 回答 1

1

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

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

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

我不确定你在管道中的哪个位置遇到了这个问题——是在你从磁盘读取的时候吗?其中一些技术可能有用:

  • 在流中处理您的数据。
  • 从 C++ 执行 I/O。
  • 从文件中分块读取数据。kMaxLength是最大索引,而不是可以使用的最大内存量。因此,如果您可以从 C++ 或流数据处理程序中(使用 )将大缓冲区读入更宽的 TypedArray typedarray.set,那么您可以返回例如0x7fffffff消耗 8,589,934,588 字节的 -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;
    });
    
于 2016-09-23T05:30:53.047 回答