0

我正在尝试读取 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 对象中的二进制数据。

4

1 回答 1

0

为子孙后代。数据编码是错误的。二进制数据表示为 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, 0, 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;
于 2021-01-05T22:15:45.193 回答