Как прочитать файл из интерфейса NAPI (node-addon) и записать в другой файл, используя файловый поток nodejs

Я пытаюсь прочитать файл в приложении NAPI и вызвать функцию обратного вызова, чтобы записать его в поток записи в приложении nodejs.

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, я получаю файл. Но я хотел бы отправить эти данные по HTTP, используя Express. Так что же происходит? Как я могу правильно обернуть и вернуть двоичные данные в объектах NAPI.


person Andy Puneri    schedule 04.01.2021    source источник


Ответы (1)


Для будущих поколений. Кодирование данных было ошибкой. Двоичные данные представлены в виде массива байтов, а затем преобразуются в буфер для использования 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;
person Andy Puneri    schedule 05.01.2021