node.js 模块学习
学习一门新语言,就要学习它的api。(ps:这笔记其实早写好了,前几天做个h5,没时间排版,等h5结束了,再总结。)
1:nodejs 文件操作
node.js不只是能做网络编程,还能操作文件
基本api
(1)小文件拷贝
var fs = require(‘fs’);
function copy(src,dst){
fs.writeFileSync(dst,fs.readFileSync(src))
}
function main(argv){
copy(argv[0],argv[1])
}
main(process.argv.slice(2))
以上代码使用fs.readFileSync 从原路径读取文件内容,使用fs.writeFileSync将文件写入目标
(2)大文件拷贝
var fs = require(‘fs’);
function copy(src,dst){
fs.createReadStream(src).pipe(fs.createWriteStream(dst));
}
function main(argv){
copy(argv[0],argv[1])
}
main(process.argv.slice(2))
使用了fs.createReadStream创建一个源文件的只读数据流,使用fs.createWriteStream创建一个只写数据流,用pipe方法把数据流连接
3:buffer缓冲 数据块
js语言只有字符串数据类型,没有二进制数据类型,所以node.js提供了一个与string对于的函数buffer来操作二进制数据
(1)var bin = new Buffer([0x68, 0x65, 0x6c, 0x6c, 0x6f]);
可以用index和length 属性
(2) 可以与字符串相互转化
var str = bin.toString(‘utf-8’);
var bin = new Buffer(‘hello’,’utf-8’)
(3) 与字符串不同,他的改变是指针类型,而字符串是得到一个新字符
因此如果拷贝Buffer,需要新创建一个Buffer,在用copy把Buffer数据复制过去
4:stream 数据流,数据的流向
因为内存无法一次性装下太多数据或者一边读取一边处理更加高效,所以用到stream数据了。
大文件拷贝,可以用只读数据流
var rs = fs.createReadStream(pathname);
rs.on(‘data’,function(chunk){
doSomething(chunk);
})
rs.on(‘end;,function(){
cleanUp();
})
加入回调
var rs = fs.createReadStream(pathname);
rs.on(‘data’,function(chunk){
rs.pause();
doSomething(chunk,function(){
rs.resume();
});
})
rs.on(‘end;,function(){
cleanUp();
})
改
var rs = fs.createReadStream(src);
var ws = fs.createWriteStream(dst);
rs.on(‘data’,function(chunk){
if(ws.write(chunk) === false){
rs.pause();
}
})
rs.on(‘end’,function(){
ws.end();
})
ws.on(‘drain’,function(){
rs.resume();
})
5:node.js 通过内置fs模块对文件操作
(1)文件属性读写
fs.stat,fs.chmod,fs.chown
(2)文件内容读写
fs.readFile,fs.readdir,fs.writeFile,fs.mkdir
(3)底层文件操作
fs.open,fs.read,fs.write,fs.close;
node.js优点在fs模块体现,异步IO模型;
fs.readFile(pathname,function(err,data){
if(err){
Deal with error
}else{
Deal with data
}
})
如果模块无法异步操作,可以用sync
try {
var data = fs.readFileSync(pathname);
// Deal with data.
} catch (err) {
// Deal with error.
}
6:path
node.js内置path模块简化操作。
var cache = {};
function store(key, value) {
cache[path.normalize(key)] = value;
}
store(‘foo/bar’, 1);
store(‘foo//baz//../bar’, 2);
console.log(cache); // => { “foo/bar”: 2 }
path.join,path.extname
7:遍历目录
遍历目录是操作文件时的一个常见需求。比如写一个程序,需要找到并处理指定目录下的所有JS文件时,就需要遍历整个目录。
(1)递归算法
function factorial(n){
if(n === 1){
return 1;
}else{
return n*factorial(n-1)
}
}
(2)遍历算法
目录是个树状结构,遍历使用深度优先+先序遍历算法
function travel(dir,callback){ //dir?,callback?
fs.readFileSync(dir).forEach(function(file){
var pathname = path.join(dir,file);
if(fs.statSync(pathname).isDirectory()){
travel(pathname,callback)
}else{
callback(pathname)
}
})
}
异步遍历
function travel(dir, callback, finish) {
fs.readdir(dir, function (err, files) {
(function next(i) {
if (i < files.length) {
var pathname = path.join(dir, files[i]);
fs.stat(pathname, function (err, stats) {
if (stats.isDirectory()) {
travel(pathname, callback, function () {
next(i + 1);
});
} else {
callback(pathname, function () {
next(i + 1);
});
}
});
} else {
finish && finish();
}
}(0));
});
}
8:文件编码
使用node.js,操作最多的就是文本文件。这就涉及到文件编码问题,常用的文本有utf8(可能带有dom)和gbk,
DOM用于编辑一个文件文件使用unicode编码,本身是一个unicode字符,位于文件头部