首次写入文件失败求助:创建文件后写入报错,二次运行正常
问题分析与解决方案
核心问题
你的代码报错根源是异步操作的执行顺序错误:fs.access是异步方法,它的回调函数不会立刻执行,但你后面的fs.readFileSync等同步代码会直接运行——首次运行时,文件还没被fs.access回调里的代码创建,fs.readFileSync就尝试读取,自然会抛出文件不存在的错误。第二次运行时文件已经存在,fs.access的回调不会执行创建逻辑,后续同步代码能正常读取文件,所以没问题。
解决方案
方案一:改用同步方法(推荐)
使用fs.accessSync替代异步的fs.access,确保文件存在检查、创建操作完成后,再执行后续的读取和写入逻辑:
exports.postMySQLconfigSave = function(request, response){ let jsonFile; let configData; try { // 同步检查文件是否存在 fs.accessSync(PathConfigFile); } catch (error) { console.log("file not exist: " + PathConfigFile); jsonFile = JSON.stringify({}); // 创建空JSON结构 fs.writeFileSync(PathConfigFile, jsonFile); } // 此时文件已确保存在,放心读取 jsonFile = fs.readFileSync(PathConfigFile, "utf8"); configData = JSON.parse(jsonFile); // 检查并初始化MySQL配置项 if (!configData.MySQL) { configData.MySQL = {}; console.log("not MySQL config"); } if (!configData.MySQL.IpAddress) { configData.MySQL.IpAddress = ""; console.log("not IpAddress MySQL"); } if (!configData.MySQL.Login) { configData.MySQL.Login = ""; console.log("not Login MySQL"); } if (!configData.MySQL.Password) { configData.MySQL.Password = ""; console.log("not Password MySQL"); } // 更新配置内容 configData.MySQL.IpAddress = request.body.IPaddressMySQL; configData.MySQL.Login = request.body.LoginMySQL; configData.MySQL.Password = request.body.PasswordMySQL; jsonFile = JSON.stringify(configData); fs.writeFileSync(PathConfigFile, jsonFile); console.log("Here was the code"); response.send("About the site"); };
方案二:将后续逻辑放入异步回调
如果坚持使用异步方法,需要把所有依赖文件存在性的逻辑都放到fs.access的回调函数内,确保执行顺序正确:
exports.postMySQLconfigSave = function(request, response){ let jsonFile; let configData; fs.access(PathConfigFile, function(error){ if (error){ console.log("file not exist: " + PathConfigFile); jsonFile = JSON.stringify({}); // 创建空JSON结构 fs.writeFileSync(PathConfigFile, jsonFile); } // 所有后续操作都放在回调内,保证文件已存在 jsonFile = fs.readFileSync(PathConfigFile, "utf8"); configData = JSON.parse(jsonFile); if (!configData.MySQL) { configData.MySQL = {}; console.log("not MySQL config"); } if (!configData.MySQL.IpAddress) { configData.MySQL.IpAddress = ""; console.log("not IpAddress MySQL"); } if (!configData.MySQL.Login) { configData.MySQL.Login = ""; console.log("not Login MySQL"); } if (!configData.MySQL.Password) { configData.MySQL.Password = ""; console.log("not Password MySQL"); } configData.MySQL.IpAddress = request.body.IPaddressMySQL; configData.MySQL.Login = request.body.LoginMySQL; configData.MySQL.Password = request.body.PasswordMySQL; jsonFile = JSON.stringify(configData); fs.writeFileSync(PathConfigFile, jsonFile); console.log("Here was the code"); response.send("About the site"); }); };
说明
推荐使用方案一,同步流程逻辑更清晰,避免回调嵌套,且该场景下同步操作的性能影响可忽略不计。
内容的提问来源于stack exchange,提问作者S F
相关产品推荐
相关产品推荐

