Node基础I/O操作 - fs模块&基于Promise封装

1,253 阅读3分钟

来个前言

  • 传统意义上的 JavaScript 运行在浏览器上,这是因为浏览器内核实际上分为两个部分:渲染引擎和 JavaScript 引擎。前者负责渲染 HTML + CSS,后者则负责运行 JavaScript。Chrome 使用的 JavaScript 引擎是 V8,它的速度非常快。
  • Node.js 是一个运行在服务端的框架,它的底层就使用了 V8 引擎。我们知道 Apache + PHP 以及 Java 的 Servlet 都可以用来开发动态网页,Node.js 的作用与他们类似,只不过是使用 JavaScript 来开发。
  • 白话理解:基于Node可以完成以下操作
  1. 实时性应用,比如在线多人协作工具,网页聊天应用等。
  2. 以 I/O 为主的高并发应用,比如为客户端提供 API,读取数据库。
  3. 流式应用,比如客户端经常上传文件。
  4. 最主要的前后端分离
  • 那今天来说说 简单的I/O操作 - fs模块

首先 let fs = require('fs');

  1. READ-DIR

读取指定目录(相对目录或者绝对目录都可以)中的文件目录

let result = fs.readdirSync('./');
console.log(result); //=>["fs1.js","note.md","node_modules"...]

异步操作是:读取成功后触发回调函数执行

 fs.readdir('./', (err, result) => {
 	//=>ERR存储读取失败后的错误信息
 	//=>RESULT存储读取成功后的结果(此时ERR=NULL)
	if (err === null) {
 		console.log(result);
 	}
});
  1. READ-FILE
  • 同步或者异步读取某一个文件中的内容
  • fs.readFileSync([path],[encoding]):不设置编码格式,默认得到的是Buffer文件流(编码)格式的数据,设置UTF8,得到的结果是字符串(例如:JSON格式、HTML或者CSS等格式);但是对于富媒体资源(例如:图片、音视频等)我们读取和传输的过程中就是基于BUFFER文件流格式操作的,所以不要设置UTF8读取;
let result = fs.readFileSync('./add.png');
console.log(result); 
 fs.readFile([path],[encoding],[callback])
 fs.readFile('./package.json', 'utf8', (err, result) => {
	if (err !== null) return;
	console.log(result);
}); 
  1. WRITE-FILE
  • 向某个文件中写入内容(如果文件不存在,它会默认创建一个文件再写入,而且写入方式是覆盖式写入“把之前文件中的内容全部覆盖”) =>appendFile是追加写入内容
  • 文件不存在可以,但是需要保证路径的正确性
//=>fs.writeFileSync([pathname],[string/buffer content],[encoding]):没有返回值
/* fs.writeFileSync('./AA.txt', '你好世界~~', 'utf8');
fs.appendFileSync('./AA.txt', 'hello world~~', 'utf8'); */
  • 异步操作的方式可以监听其成功或者失败
 fs.writeFile('./AA.txt', '哈哈哈~~我学会NODE了~~', 'utf8', err => {
	console.log(err);
}); 
// fs.writeFileSync('./js/AA.txt', '哈哈哈~~我学会NODE了~~', 'utf8'); =>这样会直接的报错 (可以基于try/catch异常捕获)
 let err = null;
try {
	fs.writeFileSync('./js/AA.txt', '哈哈哈~~我学会NODE了~~', 'utf8');
} catch (e) {
	err = e;
}
if (err !== null) {
	console.log('执行报错~~');
} 
  1. 把某个文件及里面的内容拷贝到新的目录中(替换型拷贝:原来目录中存在这个文件,新拷贝的会替换原来的)
fs.copyFile('./AA.txt', './CC.txt', err => {
	console.log(err);
}); 
  1. 创建目录
 fs.mkdir('./js', err => {
	console.log(err);
}); 
  1. 删除目录(但是一定要保证目录中不在有文件,否则不让删除)
fs.rmdir('./js', err => {
	console.log(err);
});
  1. 删除文件
fs.unlink('./js/1.js', err => {});

/* ======================= */
let {
	readFile
} = require('./utils/promiseFS');

readFile('./js/path.js').then(result => {
	console.log(result);
}).catch(reason => {
	console.log(reason);
}); 

基于Promise封装

let fs = require('fs'),
  path = require('path'),
  exportsOBJ = {};

// 根据后缀名返回编码格式:UTF8 / NULL
function suffixHandle(pathname) {
  let suffixREG = /\.([0-9a-zA-Z]+)$/,
    suffix = suffixREG.test(pathname) ? suffixREG.exec(pathname)[1] : '',
    encoding = 'utf8';
  /^(PNG|GIF|JPG|JPEG|WEBP|BMP|ICO|SVG|MP3|MP4|WAV|OGG|M3U8)$/i.test(suffix) ? encoding = null : null;
  return encoding;
}

// READ-FILE / READ-DIR / MK-DIR / RM-DIR / UN-LINK
['readFile', 'readdir', 'mkdir', 'rmdir', 'unlink'].forEach(item => {
  exportsOBJ[item] = function anonymous(pathname) {
    pathname = path.resolve(pathname);
    return new Promise((resolve, reject) => {
      let encoding = suffixHandle(pathname),
        callback = (err, result) => {
          if (err !== null) {
            reject(err);
            return;
          }
          resolve(result);
        };
      if (item !== 'readFile') {
        encoding = callback;
        callback = null;
      }
      fs[item](pathname, encoding, callback);
    });
  }
});

// WRITE-FILE / APPEND-FILE
['writeFile', 'appendFile'].forEach(item => {
  exportsOBJ[item] = function anonymous(pathname, content) {
    pathname = path.resolve(pathname);
    // 如果是 JSON 对象,我们转化为 JSON 字符串
    content !== null && typeof content === 'object' ? content = JSON.stringify(content) : null;
    typeof content !== 'string' ? content += '' : null;

    return new Promise((resolve, reject) => {
      let encoding = suffixHandle(pathname),
        callback = (err, result) => {
          if (err !== null) {
            reject(err);
            return;
          }
          resolve(result);
        };
      fs[item](pathname, content, encoding, callback);
    });
  }
});

// COPY-FILE
exportsOBJ['copyFile'] = function anonymous(pathname1, pathname2) {
  pathname1 = path.resolve(pathname1);
  pathname2 = path.resolve(pathname2);
  return new Promise((resolve, reject) => {
    fs['copyFile'](pathname1, pathname2, err => {
      if (err !== null) {
        reject(err);
        return;
      }
      resolve();
    });
  });
};
module.exports = exportsOBJ;
  • 有什么不正确的地方欢迎指出
  • 师承周啸天