依据客户须要开发了一个前后端程序,大略流程如下:
- 双击start.cmd启动nodejs服务器;
- 用户在web页面填写局部参数,提交到后盾;
- 后端应用nodejs接管前端参数,而后依据参数复写服务器上的配置文件;
- 之后应用require('child_process').spawn调用服务器上的批处理脚本;
- 脚本中调用了ANSYS的可执行文件compute.bat来计算、转换3D模型数据;
- 可执行文件compute.bat执行过程中会输入一些运行提醒文本到一个临时文件temp.dat中,提醒文本中蕴含有中文;
- 应用nodejs监听临时文件的变动,从中提取出提醒文本;
- 应用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 OFFtitle 启动服务器node ./index.jspause
双击start.cmd时,是调用了cmd.exe命令提示符执行外面的脚本,而命令提示符自身也有本人的编码方式,能够输出chcp命令查看:
流动代码页: 936
936就示意命令提示符应用的GBK编码方式,而start.cmd文件应用的UTF-8,二者不统一导致了乱码,所以解决的形式就是使二者保持一致,两种批改形式:
- 将start.cmd从新以GBK编码方式保留;
- 批改命令提示符的编码方式为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操作文件构建略微简单点的程序,踩了很多坑,这篇文章次要针对过程中的编码问题简略介绍。也是第一回在思否发略微长点的文章,文笔毛糙,各位不喜勿喷。