javascript - 使用 Node 和 FS 制作我自己的“数据库”
问题描述
所以我正在尝试创建一个数据库,几个函数片段可以读取、写入或创建 X.json 文件。我想象它的方式是一个 DB 文件夹,然后在那个文件夹中一堆用户名文件夹,还有一堆文件,比如 account.json、level.json 等等......所以每个文件夹都会保留用户数据,现在,这是我迄今为止设法编写的代码,它可以工作。但问题是,在 FS 文档上,它说在读取/写入文件之前使用 fs.stat 检查文件是否存在是一个坏主意。我不明白为什么,因为在我继续提问之前,这似乎是唯一的方法,我想在这里粘贴我的代码:
socket.on('play', (data) => {
fs.stat(`db/${data.username}/account.json`, (error, result) => {
if(!error) {
fs.readFile(`db/${data.username}/account.json`, (error, result) => {
if(error) {
throw error;
} else {
const rawResult = JSON.parse(result);
if(data.password == rawResult.password) {
socket.emit('playResponse', {
success: true,
msg: 'Login Succesfull'
});
} else {
socket.emit('playResponse', {
success: false,
msg: 'Wrong Password!'
});
}
}
});
} else if(error.code == 'ENOENT') {
socket.emit('playResponse', {
success: false,
msg: 'Account not found'
});
}
});
});
我还没有为我编写一个通用的函数,因为我认为上面的代码现在一团糟。那么,为什么在写入/读取文件之前检查文件(fs.stat)是否存在是一种不好的做法?我想我可以对从 readFile 函数得到的错误做些什么并省略该fs.stat
函数,但是每当 readFile 函数遇到一个不存在的文件夹时,我的服务器就会崩溃。
我对 Node 不是很熟悉,所以上面的代码可能完全是胡说八道。这就是我在这里的原因!
如果 readFile 遇到不存在的文件夹,如何让我的服务器不崩溃,而只是通过 socket.io 发出“找不到帐户”?如果我把那个发射代码放在那里,我的服务器无论如何都会崩溃。
我只会使用 MongoDB 或其他东西,但我有很多空闲时间,做这样的事情对我来说很有趣。> 使用像 mongo 这样的数据库更安全,还是人们这样做是为了不必浪费时间编写自己的数据库?
谢谢你的帮助!
解决方案
但问题是,在 FS 文档上,它说在读取/写入文件之前使用 fs.stat 检查文件是否存在是个坏主意。我不明白为什么
fs.exists
不推荐使用的文档中提到了原因:
不建议在调用 fs.open()、fs.readFile() 或 fs.writeFile() 之前使用 fs.exists() 检查文件是否存在。这样做会引入竞争条件,因为其他进程可能会在两次调用之间更改文件的状态。相反,用户代码应该直接打开/读取/写入文件并处理文件不存在时引发的错误。
如果 readFile 遇到不存在的文件夹,如何使我的服务器不崩溃,而只是通过 socket.io 发出“找不到帐户”?
您没有正确处理错误。例如,您在回调中抛出错误,.readFile
但您的代码未处理该错误,这将使您的应用程序“崩溃”。您可以使用try/catch
块包装您的代码或使用承诺。Promise 提供了很好的 API 来处理应用程序中的错误。Node.js v10.0.0为模块 API引入了promise-wrapped API。fs
const fs = require('fs');
const fsPromises = fs.promises;
fsPromises.readFile(`db/${data.username}/account.json`).then(error => {
// the file exists and readFile could read it successfully!
// you can throw an error and the next `catch` handle catches the error
}).catch(error => {
// there was an error
});
您还可以将 API 与try/catch
和一起使用await
:
try {
const content = await fsPromises.readFile(`db/${data.username}/account.json`);
// the file exists and readFile could read it successfully!
} catch(error) {
// handle the possible error
}
如果使用 node v10.0.0 不是一个选项,你可以使用一个 npm 包,它提供了 promise-wrapped fs API,比如fs-extra
or draxt
:
// using draxt
const $ = require('draxt');
const File = $.File;
const file = new File(`db/${data.username}/account.json`);
file.read('utf8').then(contents => {
// the file exists and readFile could read it successfully!
}).catch(error => {
// handle the possible error
});
推荐阅读
- sql - SQL查询在一行中选择父名和子名
- swift - Swift 如何显示最新的 Firebase 消息而不会出现故障滚动到最后一个索引
- python - 连接到 rabbitmq SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 警报握手失败 (_ssl.c:1108)
- javascript - 状态码 403 ...仅当来自我的服务器的请求不在本地时
- python-3.x - 如何对多边形使用 polygonPointTest 函数?
- c# - 如何手动将节点添加到链接列表 C#
- python - 从另一个命令 discord.py 调用命令
- reactjs - reactjs navlink activeClassName在root上不起作用
- c# - 从 VS Studio 2019 中的不同解决方案引用 DLL 项目?
- video - 使用 ffmpeg 进行视频编辑的推荐设置是什么?