本文,将使用fs开发一种简单的文件型数据库。

数据库中,记录将采用JSON模式,内容型如:

{"key":"a","value":"123"}

支持查询、更新、删除操作。

代码分两部分,一部分是我们将其写为模块,另一部分,是对该模块的调用。

直入主题,

模块部分(文件名:database.js):

//核心模块
var fs = require("fs");
var event_emitter = require("events").EventEmitter;

//我们的数据库,初始化参数是数据库路径(含文件名)
var database = function(path){
 this.path = path;

 this.records = Object.create(null);

 //流,写文件
 this.write_stream = fs.createWriteStream(this.path,{encoding:"utf8",flags:"a"});
 this.load()
}

//类式继承,让database具备事件能力
database.prototype = Object.create(event_emitter.prototype);

//异步操作,通过EventEmiter实现:在加载完记录后,发出load事件。
database.prototype.load = function(){

 //流,读文件
 var stream = fs.createReadStream(this.path,{encoding:"utf8"});

 var database_this = this;

 var data = "";

 //流的读取事件
 stream.on("readable",function(){
 data += stream.read();

 //以换行为分割
 var record_stream = data.split("\n");

 data = record_stream.pop();

 for(var i=0; i<record_stream.length; i++){
 var record = JSON.parse(record_stream[i]);
 if (record.value == null){
 delete this.records[record.key];
 }else{
 database_this.records[record.key] = record.value;
 }
 }
 });

 //读取完成
 stream.on("end",function(){
 database_this.emit("load");

 });
}

//根据key值,返回对应的value
database.prototype.get = function(key){
 return this.records[key]||null;
}

//写入
database.prototype.set = function(key,value,cb){
 var to_write = JSON.stringify({key:key,value:value})+"\r\n";
 if(value == null){
 delete this.records[key];
 }else{
 this.records[key] = value;
 }
 this.write_stream.write(to_write,cb);
}

//删除
database.prototype.del = function(key,cb){
 return this.set(key,null,cb);
}

module.exports = database;

重点解析:

1、EventEmitter继承,让本模块具有“事件”触发能力,可以在调用时使用on函数;

2、实例化时,输入数据库路径(如不存在,会自动创建);

3、load、get、set、del函数的实现;

4、回车换行,\r\n;

5、emit触发load事件,load事件会在调用上层响应;

6、为什么用pop();

调用部分(test13.js):

var database = require("./database");
var client = new database("./test13.db");

client.on("load",function(){
 console.log("loaded");

 console.log( client.get("my site") );

 client.set("my site","jshaman.com",function(err){
 console.log("write",err);
 })

 client.del("test2");
});

重点解析:

1、初始始化模块、传入数据库路径;

2、响应load事件,即:数据库加载完成;

3、读取、设置、删除各函数的调用。

执行效果:

数据库内容:

更多:

Node.js实战13:fs模块奥义!开发一个数据库。的更多相关文章

  1. 使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(三)

    这几篇都是我原来首发在 segmentfault 上的地址:https://segmentfault.com/a/1190000005040834 突然想起来我这个博客冷落了好多年了,也该更新一下,呵 ...

  2. Node.js实战项目学习系列(2) 开发环境和调试工具

    前言 上一节让我们对Node.js有一个初步的了解,那么现在可以开始正式学习下Node.js的开发了,但是任何一门语言要设计到开发,就必须先学习开发环境以及调试.本文将主要讲解这些内容. 本文涉及到的 ...

  3. Node.js实战2:模块使用入门。

    NodeJS有丰富的三方模块,借助这些模块,可以快速的开发各类应用.这使用Nodejs可以进行很便捷.快速的开发. 1.安装与加载模块内核.三方 使用npm可以搜索.安装.卸载模块. 例: 搜索模块 ...

  4. iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 错误处理

    沪江CCtalk视频地址:https://www.cctalk.com/v/15114923887518 处理错误请求 爱能遮掩一切过错. 当我们在访问一个站点的时候,如果访问的地址不存在(404), ...

  5. iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 记录日志

    沪江CCtalk视频地址:https://www.cctalk.com/v/15114923883523 log 日志中间件 最困难的事情就是认识自己. 在一个真实的项目中,开发只是整个投入的一小部分 ...

  6. iKcamp|基于Koa2搭建Node.js实战(含视频)☞ 视图Nunjucks

    视频地址:https://www.cctalk.com/v/15114923888328 视图 Nunjucks 彩虹是上帝和人类立的约,上帝不会再用洪水灭人. 客户端和服务端之间相互通信,传递的数据 ...

  7. Node.js实战10:“流”是Node.js最强大的功能之一。

    流是Nodejs的高级应用,掌握流的使用,才能真正胜任NodeJS开发. Nodejs中,流是基于事件的API,用于管理和处理数据,而且效率很好! 什么是流? 流是一个抽象接口,Node 中有很多对象 ...

  8. 基于 Angularjs&Node.js 云编辑器架构设计及开发实践

    基于 Angularjs&Node.js 云编辑器架构设计及开发实践 一.产品背景 二.总体架构 1. 前端架构 a.前端层次 b.核心基础模块设计 c.业务模块设计 2. Node.js端设 ...

  9. 《Node.js实战(双色)》作者之一——吴中骅访谈录

随机推荐

  1. Protobuf(一)——Protobuf简介

    Protobuf简介 ​ 什么是 Google Protocol Buffer? 假如您在网上搜索,应该会得到类似这样的文字介绍: ​ Google Protocol Buffer( 简称 Proto ...

  2. UVa11538 A Chess Queen

    A Chess Queen Problem A Chess Queen  Input: Standard Input Output: Standard Output You probably know ...

  3. muduo

    https://blog.csdn.net/zxm342698145/article/details/80689016 https://blog.csdn.net/u010087886/article ...

  4. Spring Boot 2.x整合mybatis及druid数据源及逆向工程

    1逆向工程 1)db.properties #============================# #===== Database sttings =====# #=============== ...

  5. PHP培训教程 php生成WAP页面

    WAP(无线通讯协议)是在数字移动电话.个人手持设备(PDA等)及计算机之间进行通讯的开放性全球标准.由于静态的WAP页面在很多方面不能满足用户个性化的服务请求,因此通过WAP服务器端语言产生动态的W ...

  6. 判断img的src为空/点击时候两张图片来回替换

    if($('.icon-right img').src==null){ $('.span-gray').addClass('c8'); } <img> ///////////// < ...

  7. 「树形结构 / 树形DP」总结

    Codeforces 686 D. Kay and Snowflake 要求$O(n)$求出以每个节点为根的重心. 考虑对于一个根节点$u$,其重心一定在[各个子树的重心到$u$]这条链上.这样就能够 ...

  8. C++ STL bitset总结

    基础用法 C++ Reference 神犇博客 余下的就是例题了 [BZOJ3687]简单题 考虑\(DP\),设\(f[i][j]\)表示前\(i\)个元素的算数和为\(j\)的子集个数,有: \[ ...

  9. Spring Cloud Commons教程(三)忽略网络接口

    有时,忽略某些命名网络接口是有用的,因此可以将其从服务发现注册中排除(例如,在Docker容器中运行).可以设置正则表达式的列表,这将导致所需的网络接口被忽略.以下配置将忽略“docker0”接口和以 ...

  10. java1.8 10大新特性

    http://blog.csdn.net/u013598111/article/details/49720867 一.接口的默认方法 Java 8允许我们给接口添加一个非抽象的方法实现,只需要使用 d ...