关于windows:记一次nodejs使用requirechildprocessspawn调用batcmd脚本遇到的中文乱码问题

52次阅读

共计 1855 个字符,预计需要花费 5 分钟才能阅读完成。

依据客户须要开发了一个前后端程序,大略流程如下:

  1. 双击 start.cmd 启动 nodejs 服务器;
  2. 用户在 web 页面填写局部参数,提交到后盾;
  3. 后端应用 nodejs 接管前端参数,而后依据参数复写服务器上的配置文件;
  4. 之后应用 require(‘child_process’).spawn 调用服务器上的批处理脚本;
  5. 脚本中调用了 ANSYS 的可执行文件 compute.bat 来计算、转换 3D 模型数据;
  6. 可执行文件 compute.bat 执行过程中会输入一些运行提醒文本到一个临时文件 temp.dat 中,提醒文本中蕴含有中文;
  7. 应用 nodejs 监听临时文件的变动,从中提取出提醒文本;
  8. 应用 WebSocket 像前端推送这些提醒文本,而后前端展现在界面上。

start.cmd 文件内容:

web 页面参数:

临时文件 temp.dat 内容:

客户端收到 WebSocket 音讯后展现如:

整个流程中,1、7、8 环节都有中文字符

  • 启动 nodejs 服务器的命令提示符窗口中的题目,运行过程打印的提醒文本;
  • compute.bat 执行过程输入到 temp.dat 中的文本;
  • nodejs 读取 temp.dat 中的文本。

首先,start.cmd、compute.bat、temp.dat 文件自身有相应的编码,这些批处理文件保留的编码会影响输入文本的编码。

首先 start.cmd 是我用创立的,编码为 UTF-8,双击文件关上后,

文件内容

@ECHO OFF
title 启动服务器
node ./index.js
pause

双击 start.cmd 时,是调用了 cmd.exe 命令提示符执行外面的脚本,而命令提示符自身也有本人的编码方式,能够输出 chcp 命令查看:

 流动代码页: 936

936 就示意命令提示符应用的 GBK 编码方式,而 start.cmd 文件应用的 UTF-8,二者不统一导致了乱码,所以解决的形式就是使二者保持一致,两种批改形式:

  1. 将 start.cmd 从新以 GBK 编码方式保留;
  2. 批改命令提示符的编码方式为 UTF-8,传送门——设置 CMD 默认代码页为 65001 或 936。

此时,双击 start.cmd,题目就失常显示了

因为 compute.bat 是客户提供的,temp.dat 是 compute.bat 生成的,这两个编码是统一的,都是 ANSI(ANSI 是 Windows 独有的,严格来说不能称之为编码类型,传送门——ANSI 是什么编码?)。ANSI 在国内个别就是 GBK 编码。

在应用 nodejs 读取 temp.dat 内容的时候,因为 temp.dat 是 GBK 编码,所以有如下代码:

var fs = require("fs");
var iconv = require('iconv-lite');

var result = fs.readFileSync("temp.dat", "binary");
var text = iconv.decode(Buffer.from(result, "binary"), "GBK");
console.log("【原有内容】" + text);

nodejs 自身不反对 GBK,这里用到了 iconv-lite 模块来从读取到的 Buffer 以 GBK 形式解码,后果失常展现:

这里,有三个中央的编码须要保持一致:temp.dat、nodejs 解决的编码方式、命令提示符的编码,否则展现在控制台的中文就会乱码。

因为 temp.dat 是 compute.bat 脚本生成的,而 compute.bat 脚本文件自身以何种编码方式保留会影响输入的编码,这一点也是不能疏忽的。

另外,compute.bat 执行过程产生的谬误,如果 nodejs 捕捉到了,也是须要应用 GBK 形式进行解码的:


  var {spawn} = require('child_process');

  const bat = spawn('cmd.exe', ['/c', "compute.bat"], {encoding: "buffer"});

  bat.stderr.on('data', (stderr) => {var errStr = iconv.decode(Buffer.from(stderr, "binary"), "GBK");
    console.error(errStr);
  });

  bat.on('exit', (code) => {if (code === 0) {
      // 失常退出
      cb();} else {cb({ code: code});
    }
  });

因为第一次应用 nodejs 操作文件构建略微简单点的程序,踩了很多坑,这篇文章次要针对过程中的编码问题简略介绍。也是第一回在思否发略微长点的文章,文笔毛糙,各位不喜勿喷。

正文完
 0