如何在文件变更时调用fs.readFile及Express写入后自动读取新数据
问题1:如何在文件发生变更时调用fs.readFile方法?
嘿,这个需求其实挺常见的,Node.js的fs模块自带了专门监听文件变化的API,我更推荐用fs.watch——它基于操作系统原生的文件系统事件,性能比旧的fs.watchFile好很多。
直接上代码示例,一看就懂:
const fs = require('fs'); const targetFile = './your-target-file.txt'; // 替换成你的文件路径 // 创建文件监听器 const fileWatcher = fs.watch(targetFile, (eventType, filename) => { // 只处理文件内容变更事件,过滤掉重命名这类无关事件 if (eventType === 'change' && filename) { console.log(`文件 ${filename} 刚更新了,现在读取最新内容...`); // 调用fs.readFile读取最新内容 fs.readFile(targetFile, 'utf8', (err, content) => { if (err) { console.error('读取文件时出错:', err); return; } console.log('最新文件内容:', content); // 这里可以加你需要的后续逻辑 }); } }); // 记得在程序退出或者不需要监听时关闭监听器,防止内存泄漏 // process.on('exit', () => fileWatcher.close());
小提醒:有些系统下filename可能会返回undefined,所以最好加个判断;另外eventType可能是change或rename,按需过滤就行。
问题2:Express POST路由中完成fs.writeFile后自动读取新数据
这个问题的核心是异步操作的顺序问题——fs.writeFile是异步的,如果直接在它后面调用fs.readFile,很可能还没写完就去读,拿到的还是旧数据。咱们得确保写入完成后再触发读取操作,推荐用fs.promises结合async/await的写法,逻辑清晰不嵌套。
完整的代码示例(适配你的Express场景):
const express = require('express'); const bodyParser = require('body-parser'); const fs = require('fs').promises; // 使用Promise版本的fs模块 const path = require('path'); const app = express(); // 替换成你的数据文件路径,这里假设在项目根目录下 const DATA_FILE = path.join(__dirname, 'storage.json'); // 解析POST请求的JSON数据 app.use(bodyParser.json()); // 处理POST数据的路由 app.post('/save-data', async (req, res) => { try { // 1. 获取POST请求传来的新数据 const newData = req.body; // 2. 将新数据写入文件(会清空原有内容,JSON.stringify格式化让文件更易读) await fs.writeFile(DATA_FILE, JSON.stringify(newData, null, 2), 'utf8'); console.log('新数据已成功写入文件'); // 3. 写入完成后,立即读取最新数据 const rawData = await fs.readFile(DATA_FILE, 'utf8'); const updatedData = JSON.parse(rawData); console.log('读取到的最新数据:', updatedData); // 可以把最新数据返回给客户端 res.status(200).json({ message: '数据更新并读取成功', latestData: updatedData }); } catch (err) { // 统一捕获写入或读取时的错误 console.error('数据处理出错:', err); res.status(500).json({ error: '数据处理失败,请稍后重试' }); } }); // 启动服务器 const PORT = 3000; app.listen(PORT, () => { console.log(`服务器跑在 http://localhost:${PORT} 啦`); });
如果你习惯用回调写法(不推荐,容易回调地狱),也可以这么写:
// 回调版本的实现 app.post('/save-data', (req, res) => { const newData = req.body; fs.writeFile(DATA_FILE, JSON.stringify(newData, null, 2), 'utf8', (writeErr) => { if (writeErr) { console.error('写入失败:', writeErr); return res.status(500).json({ error: '写入失败' }); } // 必须在writeFile的回调里调用readFile,确保写入完成 fs.readFile(DATA_FILE, 'utf8', (readErr, rawData) => { if (readErr) { console.error('读取失败:', readErr); return res.status(500).json({ error: '读取失败' }); } const updatedData = JSON.parse(rawData); res.status(200).json({ message: '成功', latestData: updatedData }); }); }); });
小提示:如果只是需要刚写入的数据,其实没必要再读一遍文件——直接用newData就行啦!但如果是担心写入过程中出现意外(比如文件系统出错导致写入的内容和newData不一致),那读取校验一下是很有必要的。
内容的提问来源于stack exchange,提问作者Ras
相关产品推荐
相关产品推荐

