0%

Node.js中fs模块实现配置文件的读写

在Node.js中,fs模块提供了对文件系统的访问功能,我们可以利用它来实现配置文件的读取和写入操作。正好用到,就记录一下。

准备工作

确保你的项目目录已经安装了做了npmpnpmyarn等node相关初始化,存在node_modules文件夹,这样就可以使用fs

1
const fs = require('fs');

接下来就是定义路径,我是用到年月来定义路径,并放在当前路径的storeConfigs下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const path = require('path');
const date = getDate();

// 文件夹路径 ./storeConfigs/${date.year}/${date.month}
const folderPath = path.resolve(__dirname, 'storeConfigs', `${date.year}`, `${date.month}`);

// 用date.day来定义文件名 ./storeConfigs/${date.year}/${date.month}/${date.day}
const aFilePath = path.resolve(folderPath, `${date.day}`);


// 获取当前日期
function getDate() {
const currentDate = new Date();
const year = currentDate.getFullYear();
const month = currentDate.getMonth() + 1;
const day = currentDate.getDate();
return { year: year, month: month, day: day };
}

读取配置

要实现读取的逻辑,首先要做下文件夹排空报错处理,!fs.existsSync(folderPath)假如路径不存在,那代表文件也不存在,mkdirp(folderPath);根据路径创建文件夹,再 fs.writeFileSync(aFilePath, '{}');创建文件。假如存在路径,!fs.existsSync(aFilePath)文件不存在,创建文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 if (!fs.existsSync(folderPath)) {
mkdirp(folderPath);
fs.writeFileSync(aFilePath, '{}');
} else {
if (!fs.existsSync(aFilePath)) {
console.log(`创建文件:${aFilePath}`);
fs.writeFileSync(aFilePath, '{}');
}
}

function mkdirp(dir) {
if (fs.existsSync(dir)) { return true; }
const dirname = path.dirname(dir);
mkdirp(dirname); // 递归创建父目录
fs.mkdirSync(dir);
}

在上面的代码中,我重构了mkdirp函数来创建空文件夹,而没有使用fs自带的mkdirSync(),使用后报错
Error: ENOENT: no such file or directory.Object.fs.mkdirSync,大致原因就是node.js低版本的漏洞吧,你也可以尝试直接使用下面代码代替mkdirp(folderPath);试试。

1
fs.mkdirSync(folderPath, { recursive: true }); // 递归创建路径

然后编写读取函数getHostConfigs(),通过fs.readFileSync(aFilePath, 'utf8')获取到aFilePath该文件路径下的文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function getHostConfigs() {
console.log('进入读取环节..')
const date = getDate()
const folderPath = path.resolve(__dirname, 'storeConfigs', `${date.year}`, `${date.month}`);
const aFilePath = path.resolve(folderPath, `${date.day}`);
try {
if (!fs.existsSync(folderPath)) {
mkdirp(folderPath);
fs.writeFileSync(aFilePath, '{}');
} else {
if (!fs.existsSync(aFilePath)) {
console.log(`创建文件:${aFilePath}`);
fs.writeFileSync(aFilePath, '{}');
}
}
// 读取文件配置
const data = fs.readFileSync(aFilePath, 'utf8');
const hostConfigs = JSON.parse(data);
console.log('配置校验成功!!');
return hostConfigs;
} catch (error) {
console.error('读取失败:', error);
return null;
}
}

接下来是配置的更新写入,这部分可以根据自己需求来,比较重要的是let hostConfigs = getHostConfigs();读取配置,然后在这个函数里利用fs.writeFile(aFilePath,data)实现写入逻辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function updateHostConfigs(config) {
const date = getDate()
const folderPath = path.resolve(__dirname, 'storeConfigs', `${date.year}`, `${date.month}`);
const aFilePath = path.resolve(folderPath, `${date.day}`);

let hostConfigs = getHostConfigs();
if (!hostConfigs) {
hostConfigs = {};
}
if (config.host) {
hostConfigs[config.host] = config;
}
// 写入配置
fs.writeFile(aFilePath, JSON.stringify(hostConfigs), (err) => {
if (err) {
console.error('写入出错:', err);
} else {
console.log('配置写入成功..');
}
});
console.log(hostConfigs);
}

之所以在updateHostConfigs(config)getHostConfigs()里都重新获取日期重构路径,是为了防止长期挂载脚本时,新一天内容写到旧一天文件去,
最后导出模块,方便其他脚本使用:

1
2
3
4
module.exports = {
updateHostConfigs,
getHostConfigs
};

更新日志

同步写入会出错,使用const fsSync = require('fs').promises; 进行异步写入操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
const path = require('path');
const fs = require('fs');
const fsSync = require('fs').promises;

const fileLocks = new Set();

async function updateHostConfigs(config) {
if (fileLocks.has(config.host)) {
console.log('配置正在写入,请稍后再试');
return false;
}
fileLocks.add(config.host);
const date = getDate();
const folderPath = path.resolve(__dirname, 'storeConfigs', `${date.year}`, `${date.month}`);
const aFilePath = path.resolve(folderPath, `${date.day}`);

try {
let hostConfigs = getHostConfigs(date);
if (!hostConfigs) {
hostConfigs = { count: 0 };
}
if (config.host) {
hostConfigs[config.host] = config;
hostConfigs.count++;
}
await fsSync.writeFile(aFilePath, JSON.stringify(hostConfigs));
console.log(`ID${date.day}_${hostConfigs.count} 配置已写入..`);
return true;
} catch (error) {
console.error('写入出错:', error);
return false;
} finally {
fileLocks.delete(config.host); // 解锁
}
}
-------------本文结束感谢您的阅读-------------