浅谈node ------ (2)

221 阅读3分钟

一个遍历文件夹的简单demo

const fs = require ("fs");
const path = require("path");
function bfs(dataUrl) {    
    fs.stat(dataUrl , function (err , data) {        
        if(data.isFile(dataUrl)) {            
            console.log(dataUrl);            
            return;        
        }else if (!data.isDirectory(dataUrl)) {            
            return;        
        } else {            
            fs.readdir(dataUrl , function (err , data) {                
                data.forEach(function (item , index) {                    
                    bfs(path.resolve(dataUrl , item));                
                })             
            })        
        }    
    })
}
bfs("./dir");

path是一个自动补全路径的模块

今天接着上篇文章,讲讲fs模块里的stream,watch,和http。

Stream

fs.createReadStream()

node读取文件采用流形式,就是每64k读取一次

const rs = fs.createReadStream("./111.txt" , 
            {    
               encoding : "utf-8",    
               start : 10,    
               end : 200
            });

rs.on("data" , function (data) {    
    console.log(data);
})

这段代码的意思是创建一个流对象,从文件111.txt的第10位开始读取文件,读取到第200个字符(注意,一个中文占三个字符,小心输出乱码)

//暂停读取
rs.pause();

//回复读取 resume()
setTimeout(function () {    
    rs.resume();
}, 1000);

另一种读取文件的方法,和上面的data事件效果相同

rs.on("readable" , function () {    
    var data = rs.read();    
    console.log(data)
})

读取文件结束

rs.on("end" , function () {   
 console.log("end")
})

fs.createWriteStream()

稳健的写入也是采用创建流对象进行写入的方式

const wf = fs.createWriteStream("./222.txt" , {    
    flags : "a" , //a表示拼接,w表示覆盖原文件 
});

文件开始读写
rf.on("data" , function (data) {    
    wf.write(data);
})
rf.on("end" , function () {    
    wf.close();
})

文件读写的等效

rf.pipe(wf)

watch

watch是一个监听文件变化的方法,一个简易的gulp内部机制如下

const fs = require("fs");
fs.watch("./111.txt" , "utf-8" , function (eventType , fileName) {    
    console.log(eventType,fileName);    
    const rf = fs.createReadStream("./111.txt");    
    const wf = fs.createWriteStream("./222.txt");    
    rf.on("data" , function (data) {        
        wf.write(data);    
    })    
    rf.on("end" , function () {        
        wf.close();    
    })    
    //rf.pipe(wf)
})

这就是一个简单的类似gulp监听文件修改的实现,回调函数第一个参数是文件的改动的类型,第二个参数是文件名

监听css文件,我用了autoprefixer和postcss插件,命令行cnpm安装一下就行,j就是给css3添加兼容性的前缀

const fs = require("fs");
const autoprefixer = require("autoprefixer");
const postcss = require("postcss");

fs.watch("index.css", function (eventType, fileName) {    
    fs.readFile("./index.css" , function (err , css) {        
        postcss([ autoprefixer ]).process(css).then(function (result) {            
            result.warnings().forEach(function (warn) {                
                console.warn(warn.toString());            
            });            
            fs.writeFile("./index1.css" , result.css)        
        });    
    })
}) 

http模块

首先我们需要引入node内置的http模块

const http = require("http");

我们先开启一个本地的服务器

const server = http.createServer(function (req , res) {
    res.end("server is created")
})
server.listen(3000)

回调函数的两个参数分别是请求和响应,res.end返还了相应的主体资源,你会在相应的本地3000端口上看到server is created这句话。

另一种写法,采用事件的方式

const server = http.createServer();
server.on("request" , function (req , res) {
       res.end("server is created")
})

其中请求(req)有几个属性,我们可以打印查看一下

console.log(req.headers);//请求头
console.log(req.url);//请求域名
console.log(req.method);//请求的方法
console.log(req.httpVersion);//http协议版本号

服务端读取客户端发来的请求的数据也是以流对象的形式,即每64k读取一次

var reqBody = '';    
req.on("data" , function (data) {        
    reqBody += data;    
})    
req.on("end" , function () {        
    console.log(reqBody);    
})

服务器响应客户端请求,返还请求的数据,会拼接在响应主体之前,必须在end之前,否则会报错

res.write("some ahead of res.end");

响应完毕,返还数据,没有end浏览器会一直请求

res.end("all res data");

还有一些设置响应的设置

res.statusCode = 200; //设置响应状态码
res.statusMessage = "success"; //响应状态信息
res.setHeader("content-Type" , "test.html");//设置响应头

处理服务器端口关闭的方法,一般用于端口的异常关闭手机报错信息等

server.on("close" , function () {
    ...some code;
})