无法将非ASCII文件名从NodeJS传递到C++模块

gjmwrych  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(114)

我想从NodeJS发送文件路径信息到我自己的模块(C使用node-addon-API)。每一方都独立工作(即我可以在NodeJS和C中检查/打开文件)。但是,如果想从NodeJS发送包含字符的路径变量,如ä,<$,ü等,它会失败。
这是检查路径是否存在的代码,将路径和结果写入文件并返回结果:

// PathJSON.h
#pragma once
#include <filesystem>
#include <format>
#include <fstream>
#include <string>

namespace test_json {
  std::string checkPathInJSON(const char* json) {
    std::string pathString = json;
    std::filesystem::path p(pathString);
    std::string outString = "";
    if (std::filesystem::exists(p)) {
      outString = std::format("{};exists", pathString);
    }
    else {
      outString = std::format("{};MISSING", pathString);
    }
    std::filesystem::path logPath("d:/filelog.csv");
    std::ofstream ofs(logPath, std::ios::app);
    if (ofs.is_open()) {
      ofs << outString << std::endl;
      ofs.close();
    }
    return outString;
  }
}

个字符
在C++项目中测试这段代码会给控制台和文件带来预期的结果:

// filelog.csv
D:/foo.txt;exists  // correct
D:/föö.txt;exists  // correct


下面是对应的NodeJS模块(改编自官方"hello world" example):

// hello.cc
#include <iostream>
#include <napi.h>
#include "PathJSON.h"

Napi::String Method(const Napi::CallbackInfo& info) {
  Napi::Env env = info.Env();
  std::string str = "";
  if(info.Length() == 1 && info[0].IsString()) {
    std::string par = info[0].As<Napi::String>();
    std::cout << par << std::endl;
    str = test_json::checkPathInJSON(par.c_str());
  }
  return Napi::String::New(env, str);
}

Napi::Object Init(Napi::Env env, Napi::Object exports) {
  exports.Set(Napi::String::New(env, "hello"), Napi::Function::New(env, Method));
  return exports;
}

NODE_API_MODULE(node_api_1, Init);


调用模块:

// hello.js
console.log(addon.hello("D:/foo.txt"));
console.log(addon.hello("D:/föö.txt"));


这将导致以下输出:

// filelog.csv
D:/foo.txt;exists   // correct
D:/föö.txt;MISSING  // ERROR


正如你所看到的,模块报告说,包含特殊字符(“Umlaute”)的文件不存在-然而,它正在将正确的文件名写入日志文件,我不知道问题出在哪里!
那么,我如何解决这个问题,以便我可以打开包含非ASCII字符的文件?
提前感谢您的帮助!
附言:我也尝试过使用rapidjson来传递数据(实际上,这是我通常用来传递所有信息的)。此外,我还尝试过不同的路径变体,例如D:\\föö.txtD:\\\\föö.txt等。

8zzbczxx

8zzbczxx1#

Napi::String转换为std::string会给你一个UTF-8编码的字符串,Windows文件API不支持UTF-8。
如果你转换成std::u16string,那么std::filesystem应该可以正常工作:

std::u16string par = info[0].As<Napi::String>();
std::filesystem::path p(par)

字符串

相关问题