Node.js读取ini文件后String.includes()返回false异常问题
问题排查结果
问题原因
核心问题是文件编码指定错误:
- 你读取的
Sandboxie.ini实际为带BOM的UTF-16 LE编码(Windows平台默认的Unicode文本存储格式),但代码中强制指定使用utf-8编码解码文件字节流。 - 编码不匹配直接导致两个现象:
- 文件开头的UTF-16 BOM标识(字节序列
0xFF 0xFE)不属于合法UTF-8字符,解码后被替换为乱码替换字符,就是你看到的文件开头异常乱码。 - UTF-16 LE编码下所有ASCII英文字符占2字节,格式为「原ASCII字节 + 0x00空字节」,用UTF-8解码后每个英文字母之间会插入不可见的空字符,原本连续的
Streamer字符串被拆分为带空字符间隔的序列,因此String.includes()无法匹配到目标字符串。
- 文件开头的UTF-16 BOM标识(字节序列
修复方案
选择任意一种方案即可解决:
方案1:直接指定正确编码读取
Node.js原生支持utf16le编码,修改readFileSync的编码参数即可,额外加一步去除开头可能残留的BOM字符保证兼容性:
const fs = require('fs'); // 替换编码参数为utf16le let sini = fs.readFileSync("C:\\Windows\\Sandboxie.ini", 'utf16le'); // 去除开头的BOM字符 sini = sini.replace(/^\uFEFF/, ''); console.log(sini.includes("Streamer")); // 正常返回true
方案2:自动识别BOM适配多编码场景
如果文件编码不固定,可以先读取二进制Buffer,通过BOM头自动判断编码,兼容性更强:
const fs = require('fs'); const buf = fs.readFileSync("C:\\Windows\\Sandboxie.ini"); let sini; // 根据BOM头选择对应解码方式 if (buf[0] === 0xFF && buf[1] === 0xFE) { // UTF-16 LE 带BOM sini = buf.toString('utf16le').replace(/^\uFEFF/, ''); } else if (buf[0] === 0xEF && buf[1] === 0xBB && buf[2] === 0xBF) { // UTF-8 带BOM sini = buf.toString('utf8').replace(/^\uFEFF/, ''); } else { // 无BOM默认按UTF-8解码 sini = buf.toString('utf8'); } console.log(sini.includes("Streamer"));
验证方法
如需确认问题,可在原代码中打印字符编码校验:
const idx = sini.indexOf('S'); console.log(sini.charCodeAt(idx), sini.charCodeAt(idx+1)); // 编码不匹配时会打印 83, 0 (83是'S'的字符编码,0就是错误解码插入的空字符)
内容的提问来源于stack exchange,提问作者tomiella
相关产品推荐
相关产品推荐

