fs模块读写文件随机出现空行及NaN的问题如何解决?
Node.js fs模块读写计数文件随机出现空行、NaN问题解决
根因定位
- 并发竞态冲突:discord.js的命令执行逻辑是异步并发的,你当前代码用同步读+异步写的组合,短时间内多次触发命令时,会出现前一次写入还未完成,后一次读取已经执行的情况,此时会读到不完整的损坏内容,分割后第二行不是合法数字,自增后直接变成NaN;多次写入互相覆盖也会导致文件格式错乱出现空行。
- 隐式类型转换风险:直接对读取到的字符串类型的第二行做自增运算,完全依赖JS隐式类型转换,一旦读取到空值、特殊字符等非数字内容,转换失败就会生成NaN。
- 换行符兼容问题:不同系统的换行符为
\n或\r\n,或文件写入时末尾多余换行,都会导致分割后的数组长度不符合预期,无法取到正确的第二行数值。
修复方案
- 增加全局读写锁,确保同一时间只有一个命令在操作文件,避免并发冲突
- 统一处理换行符,读取后先做格式归一再分割
- 增加内容校验和显式类型转换,异常场景下做兜底处理
- 改用同步写入,保证写入操作完成后再结束当前流程
修复后代码
const Discord = require("discord.js"); const fs = require('fs'); // 全局读写锁,避免并发操作文件 let isFileOperating = false; module.exports = { name: "testkom", aliases: [], async execute(message, args, client) { // 锁被占用时可根据业务需要选择直接返回或加入等待队列 if (isFileOperating) return; try { isFileOperating = true; // 读取文件并统一换行符格式 const fileContent = fs.readFileSync('peakcommands.txt', 'utf8').replace(/\r\n/g, '\n'); let data = fileContent.split('\n'); // 兜底校验文件格式,不符合要求时重置为初始值 if (data.length < 2) { data = ['0', '0']; } // 显式转换为数字,转换失败兜底从1开始计数 const secondLineVal = parseInt(data[1], 10); data[1] = isNaN(secondLineVal) ? 1 : secondLineVal + 1; const outputText = data.join('\n'); // 同步写入确保操作原子性 fs.writeFileSync('peakcommands.txt', outputText, 'utf8'); message.channel.send(data[1]); } catch (err) { console.error('文件操作失败:', err); } finally { // 无论操作成功失败都释放锁 isFileOperating = false; } } }
内容的提问来源于stack exchange,提问作者ziomek64
相关产品推荐
相关产品推荐

