使用Node和FS创建自己的“数据库”

时间:2018-09-08 16:00:12

标签: javascript node.js 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这样的数据库是否更安全,还是人们这样做是为了避免浪费时间编写自己的数据库?

感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

  

但是问题是,在FS文档上,它说在读/写文件之前使用fs.stat检查文件是否存在是一个坏主意。我不明白为什么

已弃用的fs.exists文档中提到了原因:

  

不建议在调用fs.open(),fs.readFile()或fs.writeFile()之前使用fs.exists()检查文件是否存在。这样做会引入竞争条件,因为其他进程可能会在两次调用之间更改文件的状态。相反,用户代码应直接打开/读取/写入文件,并处理文件不存在时引发的错误。


  

如果readFile遇到不存在的文件夹,而是通过socket.io发出“找不到帐户”,如何使服务器不崩溃?

您没有正确处理错误。例如,您在.readFile回调中引发了一个错误,但是您的代码未处理该错误,这将“崩溃”您的应用程序。您可以使用try/catch块包装代码,也可以使用promises。 Promise提供了不错的API来处理应用程序中的错误。 Node.js v10.0.0为fs模块API引入了promise-wrapped APIs

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/catchawait一起使用:

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
}

如果不选择使用节点v10.0.0,则可以使用npm软件包,该软件包提供承诺包装的fs API,例如fs-extradraxt

// 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
});