如何使用 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)
但总而言之,它是这样说的:
// 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;
});
我有一个节点 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)
但总而言之,它是这样说的:
// 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; });