You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

首次写入文件失败求助:创建文件后写入报错,二次运行正常

问题分析与解决方案

核心问题

你的代码报错根源是异步操作的执行顺序错误: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 19:20:30