问题描述
我正在尝试读取 NAPI 应用程序中的文件并调用回调函数将其写入 nodejs 应用程序中的 writestream。
exmaple_Class.cpp
void readFromTransientFile(const Napi::CallbackInfo &info)
{
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
Napi::Function cb = info[0].As<Napi::Function>();
while ((this->actualClass_->pos() < this->actualClass_->size()) &&
((readLength = this->actualClass_->read((void *)tempBuffer,sizeof(tempBuffer))) > 0))
{
//cb.Call(env.Global(),{Napi::Buffer<char>::New(env,tempBuffer,sizeof(tempBuffer))});
cb.Call(env.Global(),{Napi::String::New(env,tempBuffer)});
writetotal += readLength;
}
std::cout << "Done!" << std::endl;
}
exmaple_Class.js
const testAddon = require("./build/Release/testaddon.node");
const fs = require("fs");
const prevInstance = new testAddon.OtClass();
const writeStream = fs.createWriteStream("./downloads/lake.jpg");
prevInstance.readFromTransientFile(
function (msg) {
console.log(">> received buffer from getFile: ",msg);
console.log(">> typeof msg",typeof msg);
writeStream.write(msg);
}
);
writeStream.end();
C++ 端函数的局限是不能返回值,所以数据必须在回调中返回。有趣的是,如果它是一个文本文件,它可以正常工作,但对于其他类型的文件,如 zip 或 jpeg,我得到的数据是乱码。如果我将文件描述符传递给 C++ 函数并使用 UNIX 写入函数,那么我会得到该文件。但我也想使用 express 通过 HTTP 发送该数据。那么出了什么问题呢?如何在 NAPI 对象中正确包装和返回二进制数据。
解决方法
为了后代。数据编码是错误。二进制数据表示为Byte Array,然后转换成Buffer供writeStreamer消费。
fileReader.cpp
void functionexample::ReadRawFile(const Napi::CallbackInfo &info)
{
Napi::Env env = info.Env();
Napi::HandleScope scope(env);
// nodejs callback
Napi::Function cb = info[0].As<Napi::Function>();
char *file_name = "lake.jpg";
int i = 0;
const int BLOCK_SIZE = 1024;
char buffer[BLOCK_SIZE];
ifstream ifs;
ifs.open(file_name,ifstream::binary | ifstream::in);
while (1)
{
memset(buffer,BLOCK_SIZE);
ifs.read(buffer,BLOCK_SIZE);
cout << i << " | buffer size: " << ifs.gcount() << endl;
i++;
/// PASSING DATA TO THE NODEJS APPLICATION
/// AS A BINARY ARRAY PPINTER POINTING TO THE buffer
cb.Call(env.Global(),{Napi::ArrayBuffer::New(env,buffer,ifs.gcount())});
ofs.write(buffer,ifs.gcount());
if (!ifs)
break;
}
ifs.close();
}
fileWriter.js
const fs = require("fs");
const testAddon = require("./build/Release/testaddon.node");
// Create a write streamer
const wstream = fs.createWriteStream("./lake-copied-nodejs.jpg");
testAddon.readFile(function(msg) {
// handle data encoding
const buf = Buffer.alloc(msg.byteLength);
const view = new Uint8Array(msg);
for (var i = 0; i < buf.length; ++i) {
buf[i] = view[i];
}
// write binary data to file
wstream.write(buf);
});
wstream.close();
module.exports = testAddon;