Node.js调用fs.writeFile时报ERR_INVALID_ARG_TYPE错误如何解决?
报错原因
直接触发原因是你调用fs.writeFile()写入login.conf时,传入的第二个参数login是split(':')返回的数组类型,而Node.js的文件写入API只支持传入字符串、Buffer、TypedArray、DataView这几类数据,类型不匹配直接抛出报错。
TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received an instance of Array
除此之外你的代码还存在多处逻辑问题,无法实现需求:
- 异步执行顺序混乱:
fs.writeFile、child_process.exec均为异步方法,当前写法会出现文件还未写入完成就执行ovpnconnector、还未拿到程序执行结果就写入输出文件的问题 - 内容处理逻辑错误:多次无意义的字符串切割、拼接操作,没有实现「按:分割每一行拆为两行写入」的需求
- 语法错误:判断运行结果时使用赋值运算符
=而非比较运算符===,work、holder变量未声明未赋值,循环变量和外层变量重名 - 没有按行处理输入文件内容,不符合需求
修复方案
以下是可直接运行的修正代码:
const fs = require('fs/promises'); const { exec } = require('child_process'); const util = require('util'); const execPromise = util.promisify(exec); const path = require('path'); const confPath = path.join(__dirname, 'login.conf'); const inputDir = path.join(__dirname, 'input'); const workingOutputPath = path.join(__dirname, 'output/working.txt'); const notWorkingOutputPath = path.join(__dirname, 'output/not_working.txt'); // 提前创建output目录避免写入报错 async function initDir() { try { await fs.access(path.join(__dirname, 'output')); } catch { await fs.mkdir(path.join(__dirname, 'output')); } } async function main() { await initDir(); // 读取输入目录下的所有文件 const files = await fs.readdir(inputDir); for (const file of files) { const filePath = path.join(inputDir, file); // 读取文件内容 const content = await fs.readFile(filePath, 'utf8'); // 按行拆分内容,过滤空行 const lines = content.split(/\r?\n/).filter(line => line.trim() !== ''); for (const line of lines) { // 按:分割为两部分 const [username, password] = line.split(':').map(item => item.trim()); if (!username || !password) continue; // 拼接为两行写入login.conf const loginContent = `${username}\n${password}`; await fs.writeFile(confPath, loginContent); try { // 执行ovpnconnector命令,等待执行完成 await execPromise(path.join(__dirname, 'ovpnconnector.exe start nordvpn.ovpn')); // 执行成功追加写入有效文件 await fs.appendFile(workingOutputPath, `${line}\n`); console.log(`有效: ${line}`); } catch (err) { // 执行失败追加写入无效文件 await fs.appendFile(notWorkingOutputPath, `${line}\n`); console.log(`无效: ${line}`); } } } } main().catch(err => console.log('运行出错:', err));
核心修改点
- 改用
fs.promises和util.promisify包装异步API,配合async/await保证执行顺序正确 - 正确实现内容处理逻辑:按行拆分输入文件,每行按
:分割后拼接为换行分隔的字符串再写入配置文件 - 正确捕获命令执行结果,通过退出码判断是否运行成功,分别写入对应结果文件
- 使用
path.join处理路径,兼容不同系统的路径分隔符 - 提前创建输出目录,补全错误处理逻辑
内容的提问来源于stack exchange,提问作者Fisheiyy
相关产品推荐
相关产品推荐

