js是脚本语言,对于html中的js,浏览器作为解析器(运行环境);对于单独的js,node作为解析环境。
浏览器中操作DOM,提供document等内置对象;NODEJS操作磁盘文件or搭建HTTP服务器,提供fs、http等内置对象。
所有模块执行过程中只初始化一次。
模块路径:
1.内置模块直接调用如require(‘fs’)
2.node_modules目录下如某个绝对路径为’/home/user/h.js’的文件中require(‘foo/bar’),则使用的路径依次为/home/user/node_modules/foo/bar或者/home/node_modules…或者/node_modules/…
3.NODE_PATH环境变量(尝试额外的搜索路径)
下载第三方数据包,可以先写入package.json,再npm insatall.
文件读取
1 | //异步拷贝 |
windows命令行复制文件:如将d:\1.jpg复制到f盘根目录——copy d:\1.jpg f:\1.jpg
所以可以在node中调用命令行实现文件复制:1
2
3
4
5
6
7
8
9
10
11
12
13
14var child_process = require('child_process');
var util = require('util');
function copy(source, target, callback) {
child_process.exec(
util.format('copy %s %s', source, target), callback);// %s依次使用后面的字符串替换,所谓的格式化就是变量替换嘛
}
copy('C:\\Users\\hank.li\\Desktop\\hank\\s.png', 'C:\\Users\\hank.li\\Desktop', function (err) {
console.log(err);
});
//坑:双斜线防止转义啊!斜线方向要注意啊!
//exec命令行开启执行子进程
//spawn cluster
其他API:
buffer:处理二进制数据
stream:内存一次装不下以及需要边读取边处理
var a = fs.createReadStream(pathname); //只读流
b = fs.createWriteStream(dst);
a.on(‘data’,function(chunk){b.write(chunk)})
a.on(‘end’,function(){b.end()})
基于事件机制的,stream实例继承自node中的eventEmitter
灵活使用回调,比如防止读取data太快导致后续函数处理不过来,可使用回调,即在处理函数前暂停读取,然后dosomething(chunk,function(){}).
最好加一步判断是否会爆仓(写入太慢读取太多),写入时a.on(‘data’,…)中判断b.write(chunk)===false,成立的话说明传入的数据放到缓存了还没写入目标,先暂停读取。另添加一个监听 b.on(‘drain’,function(){启动read}),drain事件用于判断缓存数据已写入目标。其实这与pipe实现很类似。(注意读写之间来不及处理的数据放在缓存中!)
文件系统:关于fs模块。(此处展示node异步)
属性读写:stat(判断文件还是目录) chmod(异步方式改变文件读写权限) chown(更改文件所有权)
内容读写: readFile(异步读取) readdir(读取目录directory,返回包含所有文件和子目录的数组) writeFile mkdir(新建目录,fs.mkdir(‘./xxx’,function(err){}))
底层文件操作:open read write close
上述均为异步且都有同步方法。回调参数基本都有两个,错误+返回执行结果。
Path:处理文件路径
normalize 标准化路径。实例:path.normalize(‘foo//baz//../bar’)得出foo/bar(多余斜杠会取消,..会回退上一级)
join 拼接路径。实例:path.join(‘foo/‘,’baz/‘,’../bar’)得出foo/bar
extname 返回扩展名,从最后一个.开始计算。如返回’.js’之类。
遍历目录
递归算法:简洁但是耗内存
遍历算法:树状结构目录,深度优先+先序遍历,即优先子集而非同级元素+首次到达某节点即遍历完成。
一个文件重命名demo:1
2
3
4
5
6
7
8//demo入口文件index.js放在test文件夹同级
var counter = 9;
fs.readdir('./test',function(err,files) { //读取test文件夹中的所有txt文件
files.forEach(function(fn){
fs.renameSync('./test/'+fn,'./test/'+counter+'.txt');//fn只是test中的文件,重命名需加上目录。将前者重命名为后者(升序排列)。此处路径也是相对index文件所在目录
counter++;
})
同步遍历:1
2
3
4
5
6
7
8
9
10//遍历index的同级文件夹
function travel(dir,aa) {
fs.readdirSync(dir).forEach(function(file){
var pathname = path.join(dir,file);//这里插入一个判断是目录还是文件(fs.statSync(pathname).isDirectory()),是目录的话就回调遍历函数。stat返回值是一个标志对象。
aa(pathname);
})
}
travel('./',function aa(pathname){
console.log(pathname)
});
异步遍历:略。
文本编码
常用文本编码主要是GBK(国家编码,包含全部中文字符)和UTF-8(国际编码)。二者之间通过unicode编码进行转换。
BOM 隐藏字符(UTF-8允许含BOM)
读取文本文件需去BOM,即:1
2
3
4
5
6
7function read(pathname) {
var bin = fs.readFileSync(pathname);//返回一个字符串(buffer二进制数据),如果声明encoding则返回普通字符串(添加第2个参数{encoding:'utf-8')
if(bin[0]===0xEF && bin[1]===0xBB && bin[2]===0xBF) {
bin = bin.slice(3);//BOM被去除
}
return bin.toString('utf8');//转换成utf8编码(测试过转为汉字)
}
字符编码参考网站:https://www.cnblogs.com/xiaomia/archive/2010/11/28/1890072.html