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

时间:2016-07-21 22:59:41

标签: node.js node.js-addon node.js-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时使用任意长度的缓冲区?

1 个答案:

答案 0 :(得分:1)

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

如果你在不使用NAN的情况下为缓冲区分配内存,那么你可以达到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,那么您可以返回例如一个0x7fffffff - 长度的Uint32Array消耗8,589,934,588字节。

    // 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;
    });