Common.js和Node.js模块(文件系统 、第三方包)

cnpm init –yes 强制启动

简介

  1. Commonjs规范的提出,弥补javascript没有标准的缺陷,提供一个类似后端语言的标准库,也就是说commonjs是模块化的标准,nodejs就是commonjs模块化的实现。在nodejs中http,url,fs等等都是nodejs的内置模块,可以直接使用。
  2. commonjs自定义模块的实现
    nodejs中将公共的功能抽离为单独的js文件作为模块,在外部是没有办法访问的(类似后端的私有的属性和方法);
  3. 要想使用模块,就必须在模块里面通过exports或者module.exports暴露属性或者方法。在需要的模块使用require引入模块。
    在这里插入图片描述

使用

  1. 新建app.js文件,因为默认启动时加载的是app.js文件。
    这是后面强制启动cnpm时的显示选项

接口暴露方法:export default http或者 module.export = http;

//1. 发送请求
const http = require("http");
const url = require("url");

http.createServer((req, res) => {
    if (req.url != "/favicon.ico") {
        let path = url.parse(req.url,true);
        let query=path.query;
        console.log(path.query);
        res.writeHead(200, { "Content-Type": "text/html;charset=utf-8" });
        // 响应的数据
        res.write("解析路径传值:"+JSON.stringify(query));
        res.end();
}).listen(8080, "localhost", () => {
    console.log("creat success");
})
//接口暴露
module.export=http;//或者使用 export default http
  1. 在自定义的外部文件中如果想使用app.js里的接口,require请求,通过相对路径引入暴露的接口let server=require('app');

怎样require直接使用(自定义)文件名,像使用本地接口直接 let url =require('url'),不用写明相对路径?

解决:
nodejs 可以自动找node_modules文件下的文件,将自己的代码封装在node_modules目录下的文件里,在外部文件中就可以通过文件名请求
在这里插入图片描述

步骤:函数暴露示例

  • cnpm init 启动cnpm ,根据自己的情况选择合适选项
    执行后目录下出现package.json文件
    在这里插入图片描述
  • 我把上文代码中的请求服务函数内容封装在了node_modules下的新文件createServer中(并给这个方法配置他需要的模块)
const url = require("url");
module.exports=(req,res)=>{
    if (req.url != "/favicon.ico") {
        let path = url.parse(req.url,true);
        let query=path.query;
        console.log(path.query);
        // 响应头的编码格式
        res.writeHead(200, { "Content-Type": "text/html;charset=utf-8" });
        // 响应的数据
        res.write("解析路径传值:"+JSON.stringify(query));
        res.end();
    }
}
  • 这样就可以简化server里的代码,因为将方法暴露出去,所以再使用时require(‘文件名’)引入就可使用
//1. 发送请求
const http = require("http");
let server=require('createServer'); //直接通过名称引入

//2. 使用api的方法 创建服务器(请求服务)
http.createServer(server).listen(8080, "localhost", () => {//使用封装在米快里的方法server
    console.log("creat success");
})

对象暴露

  1. 在node_modules下新建getData.js,并将对象暴露出去
let stu=[
    {
        "name":"张三",
        "sex":"男",
        "age":18
    },
    {
        "name":"李四",
        "sex":"男",
        "age":23
    },
    {
        "name":"五三",
        "sex":"男",
        "age":22
    },

]
module.exports=stu;
  1. node_modules下的createServer.js里请求数据
let stu = require('../model/getUserData');
  1. 输出数据测试即可
const url = require("url");
let stu = require('../model/getUserData');

//加载文件流模块
let stream = require('../model/filestream');
module.exports = (req, res) => {
    if (req.url != "/favicon.ico") {
        let path = url.parse(req.url, true);
        let query = path.query;
        console.log(path.query);
        // 响应头的编码格式
        res.writeHead(200, { "Content-Type": "text/html;charset=utf-8" });
        // 响应的数据
        console.log(stu);
        res.write("解析路径传值:" + JSON.stringify(stu));

        res.end();
    }
}

后台模拟操作数据库增删改查的封装方法

//模拟操作数据库的增删改查
let connection=(callback)=>{
//连接数据库

}
//封装方法二
module.exports.insertData=(res)=>{
    connection(()=>{

    });
}
//封装方法三 自执行函数
modulu.exports=(()=>{

})();
//es6类封装
class mysql{
    constructor(){

    }
    insert(){
        
    }
    updata(){

    }
    delete(){

    }
}

加密解密

md5-node包 单向加密
  1. 安装 cnpm install md5-node –save-dev
    安装完之后项目里面生成一个node_modules依赖文件
  2. 使用:
//单向加密模块 不能解密
let md5 = require('md5-node')
base64 双向加密模块
  1. 安装 cnpm install –-save-dev js-base64
    安装完之后项目里面生成一个node_modules依赖文件
  2. 使用:

一定要.Base64

//双向加密模块
let base = require('js-base64').Base64

 //base64
        let test = base.encode(JSON.stringify(stu));//encode加密
        console.log(test);
        let str = base.decode(test);//decode 解密
        console.log(str);

文件流系统

  1. 文件流模块 fs 是node的内置模块
  2. 文件读写等操作
  3. fs中的方法分为同步或异步
  4. __dirname 是当前文件的相对上级目录
    例如下图:console.log(__dirname ); // D:\node\Mystudy1\model在这里插入图片描述
  5. mode - 文件创建默认权限为 0666(可读,可写)。设置目录权限,默认为 0777可读可写可执行)。
  1. 新建文件filestream.js
  2. //引入文件模块 let fs=require('fs')
  3. 暴露接口(以函数方法)
1. 文件读取

异步读取文件(已经新建了静态资源文件目录,新建文本文档txt:这是我的一小段测试文字)

Buffer :一个缓冲池

module.exports=()=>{
    console.log("文件流系统正在运行");
    //1. 异步读取文件
    fs.readFile("public/test.txt",(err,data)=>{
        if(err){
            throw err;
        }
        console.log(data);//<Buffer e8 bf 99 e6 98 af e6 88 91 e7 9a 84 e4 b8 80 e5 b0 8f e6 ae b5 e6 b5 8b e8 af 95 e6 96 87 e5 ad 97 0d 0a>
    });
}

结果输出数据为16进制码,在上段代码中加修改,需要转换成字符串后输出

tostring 里的格式和源文件一致即可
在这里插入图片描述

console.log(data.toString('utf-8'));  //这是我的一小段测试文字
  1. 同步读取文件
  //2. 同步读取文件
    let tb=fs.readFileSync("public/test.txt",'utf-8');
    console.log(tb);

异步读取和同步读取的区别:异步读取文件的时候由操作系统在后台进行读取,不会阻碍下面的代码执行。同步读取的时候会阻碍下面的代码执行。


let fs = require('fs')  //获取fs模块
module.exports = () => {
     //1. 异步读取文件
    console.log("异步读取start");
    fs.readFile("public/test.txt", (err, data) => {
    //读取文件,回调函数第一个参数表示错误信息,第二个参数为读取的文本内容
        if (err) {
            throw err;
        }
        else {
            console.log("异步读取end");
            console.log(data.toString('utf-8'));
        }
    });

    //2. 同步读取文件
    console.log("同步读取start");
    let tb = fs.readFileSync("public/test.txt", 'utf-8');
    console.log(tb);
    console.log('同步读取end');
}

输出结果为:
在这里插入图片描述

可见:异步读取开始、同步读取开始、同步读取结束、异步读取结束。
异步读取没有结束,同步读取就完成了。
结论:异步读取没有阻塞下面代码的执行。

2. 打开文件
2.1 异步打开文件

同步和异步的区别上文已经提过

  1. 格式
fs.open(path, flags , [mode], callback)
  1. 参数含义

path - 文件的路径。

flags - 文件打开的行为。

mode - 设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。

callback - 回调函数,带有两个参数如:callback(err, fd)。

在这里插入图片描述

  1. 实例
    我们在之前创建的filestream.js 文件里打开 test.txt 文件进行读写
let fs = require("fs");

  //异步打开文件
    fs.open("public/test.txt", 'r+', (err, fd) => {
        if (err) {
            console.log("文件打开失败");
            throw err;
        }
        console.log("当前文件已打开");
    });
执行结果为:
当前文件已打开
2.2 同步打开文件(不常用)
    //同步打开文件
    let tb=fs.openSync("public/test.txt", 'r+');
    console.log(tb);
    返回值为随机数字时说明返回成功
3. 获取文件信息
  1. 格式(异步)
fs.stat(path, callback)
  1. 参数含义

path - 文件路径。

callback - 回调函数,带有两个参数如:(err, stats), stats 是 fs.Stats 对象。
在这里插入图片描述

  1. 实例
    fs.stat("public/test.txt", (err, stats) => {
        if (err) {
            console.log("文件打开失败");
            throw err;
        }
        console.log(stats.isFile());//true
    });
4. 写入文件

当前写入内容会覆盖文件原有内容

4.1 异步
  fs.writeFile("public/test.txt", "这是我写入的数据", (err) => {
        if (err) {
            throw err;
        }
    });

直接追加到文件中的写入方法不会覆盖原有的内容

    fs.appendFile ("public/test.txt", "再一次写入看看会不会覆盖", (err) => {
        if (err) {
            throw err;
        }
    });
4.2 同步
    //同步
    fs.writeFileSync("public/test.txt","这是我同步写入的数据");
5. 读取文件
  1. 不断地将文件中的一小块内容读入缓存区,最后从该缓存区中读取文件内容
  2. 一个汉字或中文字符3个字节,英文字母或符号1个字节
  3. 什么是文件描述符fd?
    文件描述符(file descriptor)在形式上是一个非负整数。实际上,它是一个索引值,每一个文件描述符会与一个打开文件相对应。
  1. 语法

该方法使用了文件描述符来读取文件。

fs.read(fd, buffer, offset, length, position, callback)
  1. 参数

fd - 通过 fs.open() 方法返回的文件描述符。

buffer - 数据写入的缓冲区。

offset - 缓冲区写入的写入偏移量。

length - 要从文件中读取的字节数。

position - 文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。

callback - 回调函数,有三个参数err, bytesRead, buffererr 为错误信息, bytesRead表示读取的字节数,buffer 为缓冲区对象。

  1. 底层源码:
fs.read = function(fd, buffer, offset, length, position, callback) {
  if (!util.isBuffer(buffer)) {
    // legacy string interface (fd, length, position, encoding, callback)
    var cb = arguments[4],
        encoding = arguments[3];
    assertEncoding(encoding);
    position = arguments[2];
    length = arguments[1];
    buffer = new Buffer(length);
    offset = 0;
    callback = function(err, bytesRead) {
      if (!cb) return;
      var str = (bytesRead > 0) ? buffer.toString(encoding, 0, bytesRead) : '';
      (cb)(err, str, bytesRead);
    };
  }
  function wrapper(err, bytesRead) {
    // Retain a reference to buffer so that it can't be GC'ed too soon.
    callback && callback(err, bytesRead || 0, buffer);
  }
  binding.read(fd, buffer, offset, length, position, wrapper);
};
  1. 实例
   let buffer = new Buffer(500);
    //异步打开文件
    fs.open("public/data.txt", 'r+', (err, fd) => {
        if (err) {
            throw err;
        }
        fs.read(fd, buffer, 0, buffer.length, 0, (err, bytes) => {
            if (err) {
                console.log(err);
            }//读取出来的数据存放在buffer中
            fs.writeFile("public/test.txt", buffer.toString("utf-8"), (err) => {
                if (err) {
                    throw err;
                }
                console.log("写入成功");
            });
        });
        
    });
6. 关闭文件
  1. 语法(异步)
fs.close(fd, callback)
  1. 参数

fd - 通过 fs.open() 方法返回的文件描述符。
callback - 回调函数,没有参数

  1. 实例
  //文件关闭
    fs.open("public/data.txt", 'r+', (err, fd) => {
        if (err) {
            throw err;
        };
        console.log("文件打开成功!");
        fs.close(fd,(err)=>{
            if (err) {
                throw err;
            };
            console.log("文件关闭成功");
        });
    });
7. 截取文件
  1. 语法(异步模式)
fs.ftruncate(fd, len, callback)
  1. 参数

fd - 通过 fs.open() 方法返回的文件描述符。

len - 文件内容截取的长度。

callback - 回调函数,没有参数。

  1. 实例
 //存储截取后的字符
    let buffer = new Buffer(1024);
    //打开文件
    fs.open("public/test.txt", 'r+', (err, fd) => {
        if (err) {
            throw err;
        };
        //截取文件
        fs.ftruncate(fd, 100, (err) => {
            if (err) {
                throw err;
            };
            console.log("文件截取成功");
        });
        //读取截取后的文件
        fs.read(fd, buffer, 0, buffer.length, 0, (err, bytes) => {
            if (err) {
                console.log(err);
            }
            console.log(buffer.toString('utf-8'));
        });
        //关闭文件
        fs.close(fd,(err)=>{
            if(err){
                throw err;
            }
        });
    });
8.删除文件
  1. 语法(异步)
fs.unlink(path, callback)
  1. 参数

path - 文件路径。

callback - 回调函数,没有参数。

  1. 实例
  fs.unlink("public/data.txt",(err)=>{
        if(err){
            throw err;
        }
        console.log("文件删除成功!");
    });
9.创建目录
  1. 语法
fs.mkdir(path, [options], callback)
  1. 参数

path - 文件路径。

options 参数可以是:

recursive - 是否以递归的方式创建目录,默认为 false。
mode - 设置目录权限,默认为 0777
callback -> 回调函数,没有参数。

  1. 实例
    // 创建目录
   fs.mkdir("public/${testname}",(err)=>{
       if(err){
           throw err;
       }
       console.log("文件创建成功");
   });

   
    //反编译绑定文件名
    let testname="zmttesttwo";
   fs.mkdir(`public/${testname}`,(err)=>{ //注意反编译的写法 没有双引号!
       if(err){
           throw err;
       }
       console.log("文件创建成功");
   });

在这里插入图片描述

10.读取目录
  1. 语法
fs.readdir(path, callback)
  1. 参数

path - 文件路径。

callback - 回调函数,回调函数带有两个参数err, files
err 为错误信息,files 为 目录下的文件数组列表。

  1. 实例
 fs.readdir("public", (err, files) => {
        if (err) {
            console.log(err);
        }
        console.log(files);//[ 'test.txt', 'zmtTest', 'zmttesttwo' ]
        //遍历数组输出
        files.forEach((file) => {
            console.log(file);
        });
    });
  1. 读取固定目录,判断里面的所有子目录是文件还是文件夹:
  //递归遍历目录里面的每一层
    let pathinfo = "public"
    let method = (path) => {
        fs.readdir(path, (err, files) => {
            if (err) {
                throw err;
            }
           //遍历子目录
            files.map((value, index) => {
                fs.stat(path + `/${value}`, (error, stats) => {
                    if (error) {
                        throw error;
                    }
                    //开始判断是否是目录还是文件
                    if (stats.isFile()) {
                        console.log(value + "是文件");
                    }
                    else if (stats.isDirectory()) {
                        console.log(value + "是目录");
                        method(path + `/${value}`);
                    }
                });
            });
        });
    }
    method(pathinfo);
11.删除目录
  1. 语法

区分此方法(删除目录)和删除单文件unlink

fs.rmdir(path, callback)
  1. 参数

path - 文件路径。

callback -> 回调函数,没有参数。

  1. 实例
 fs.rmdir("public/zmtTest",function(err){
        if (err) {
            return console.error(err);
        }
        console.log("读取 /public 目录");
        //读取删除后的文件
        fs.readdir("public/",function(err, files){
           if (err) {
               return console.error(err);
           }
           files.forEach( function (file){
               console.log( file );
           });
        });
     });
优化:检测目录

检测文件是否存在


    fs.exists("public/zmt", (exist) => {
        //如果文件不存在
        if (!exist) {
            // 创建目录
            fs.mkdir("public/zmtTest", { mode: 0777 }, (err) => {
                if (err) {
                    throw err;
                }
                console.log("文件创建成功");
              
            });
        } else {
            console.log("该文件存在");
        }
        //执行相关操作 如添加子目录写入内容等
        fs.appendFile("public/zmtTest/addfile", "我正在写入内容!", (err) => {
            if (err) {
                throw err;
            }
            console.log('写入成功');
        });
    });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值