Path
提供了一些工具函数,用于处理文件与目录的路径
basename、dirname与extname
- 返回一个
path 的最后一部分
- 返回一个
path 的目录名
- 返回
path 的扩展名
const {basename,dirname,extname} = require("path");
const filePath = "/usr/local/bin/test.txt";
console.log(basename(filePath)); console.log(dirname(filePath)); console.log(extname(filePath));
|
join、normalize与resolve
path.join() 方法使用平台特定的分隔符把全部给定的 path 片段连接到一起,并规范化生成的路径
path.normalize() 方法会规范化给定的 path,并解析 '..' 和 '.' 片段
path.resolve() 方法会把一个相对路径解析为一个绝对路径
path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
path.join('foo', {}, 'bar');
|
path.format与path.parse
path.format() 方法会从一个对象返回一个路径字符串。 与 path.parse() 相反
path.parse() 方法返回一个对象,对象的属性表示 path 的元素
const {parse,format} = require("path");
const filePath = "/usr/local/bin/test.txt";
const parse_ret = parse(filePath); const format_ret = format(parse_ret)
console.log(parse_ret); console.log(format_ret);
|
{ root: '/', dir: '/usr/local/bin', base: 'test.txt', ext: '.txt', name: 'test' } /usr/local/bin\test.txt
|
sep、delimiter、win32、posix
和操作系统有关的东西
sep:提供了平台特定的路径片段分隔符
path.win32提供了 path 方法针对 Windows 的实现
posix 属性提供了 path 方法针对 POSIX 的实现
delimiter 就是 ":"
const {sep,delimiter,win32,posix} = require("path");
const filePath = "/usr/local/bin/test.txt";
console.log("sep ",sep); console.log("posix sep ",posix.sep); console.log("win32 sep ",win32.sep); console.log("PATH",process.env.PATH); console.log("delimiter ",delimiter);
|
sep \ posix sep / win32 sep \ PATH C:\Python27\;C:\Python27\Scripts;C:\Windows\system32;C:\Windows;C:\Windows\ System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files\Git\b in;C:\Program Files\nodejs;;e:\Program Files\VS Code\bin;C:\Users\Administrator\ AppData\Roaming\npm;.;;.;;.; delimiter ;
|
回顾小结
const path = require("path")
console.log("__dirname", __dirname); console.log("__filename", __filename); console.log("process.cwd()", process.cwd()); console.log("./", path.resolve());
|
__dirname、__filename 总是返回文件的绝对路径
process.cwd()总是返回node命令所在文件夹(就是用户在哪里启动的node脚本的路径)
Buffer
- buffer用来处理二进制数据流的
- 类似于整数数组,大小固定
Buffer 类在 Node.js 中是一个全局变量,因此无需使用 require(‘buffer’).Buffer
const buf1 = Buffer.alloc(10)
const buf2 = Buffer.alloc(10, 1);
const buf4 = Buffer.from([1, 2, 3]);
|
Buffer类常用的方法
byteLength 计算字符串占了几个字节
Buffer.isBuffer判断是否是buffer对象
Buffer.concat拼接Buffer
console.log(Buffer.byteLength("test")) console.log(Buffer.byteLength("测试"))
console.log(Buffer.isBuffer({})) console.log(Buffer.isBuffer(Buffer.from([1,2,3])))
const buf1 = Buffer.from("This ") const buf2 = Buffer.from("is ") const buf3 = Buffer.from("a ") const buf4 = Buffer.from("test ") const buf5 = Buffer.from("buffer")
const buf = Buffer.concat([buf1,buf2,buf3,buf4,buf5]);
console.log(buf.toString());
|
Buffer实例常用方法
buf.length
buf.toString()
buf.fill() 填充一些值
buf.equals() 两个buffer的内容是否相等
buf.indexOf() 找到字符的位置
buf.copy()
const buf = Buffer.from("This is a test!");
console.log(buf.length);
console.log(buf.toString("base64"));
const buf1 = Buffer.allocUnsafe(10);
console.log(buf1) console.log(buf1.fill(10,2,6))
const buf2 = Buffer.from("test") const buf3 = Buffer.from("test") const buf4 = Buffer.from("test!")
console.log(buf2.equals(buf3)) console.log(buf2.equals(buf4))
console.log(buf2.indexOf("es")); console.log(buf2.indexOf("esa"));
const StringDecoder = require("string_decoder").StringDecoder; const decoder = new StringDecoder("utf8"); const buf5 = Buffer.from("中文字符串");
for (let i=0;i<buf5.length;i+=5) { const b = Buffer.allocUnsafe(5); buf5.copy(b,0,i); console.log(b.toString()); }
for (let i=0;i<buf5.length;i+=5) { const b = Buffer.allocUnsafe(5); buf5.copy(b,0,i); console.log(decoder.write(b)); }
|
event
大多数 Node.js 核心 API 都采用惯用的异步事件驱动架构,其中某些类型的对象(触发器)会周期性地触发命名事件来调用函数对象(监听器)
eventEmitter.on() 方法用于注册监听器,eventEmitter.emit() 方法用于触发事件
- 这和在浏览器上不同,在浏览器上靠的是用户做的一些UI的操作触发,如
click\hover
const EventEmitter = require("events");
class CustomEvent extends EventEmitter {}
const ce = new CustomEvent();
ce.on("test",()=>{ console.log("This is a test"); })
setInterval(()=>{ ce.emit("test"); },500)
|
const EventEmitter = require("events");
class CustomEvent extends EventEmitter {}
const ce = new CustomEvent();
ce.on("error",(err,time) => { console.log(err); console.log(time); })
ce.emit("error", new Error("出错了"),Date.now())
|
const EventEmitter = require("events");
class CustomEvent extends EventEmitter {}
const ce = new CustomEvent();
ce.once("test",()=> { console.log("test event once"); })
setInterval(()=>{ ce.emit("test"); },500)
|
const EventEmitter = require("events");
class CustomEvent extends EventEmitter {}
function fn1() { console.log("fn1") } function fn2() { console.log("fn2") }
const ce = new CustomEvent();
ce.on("test",fn1); ce.on("test",fn2);
setInterval(()=>{ ce.emit("test"); },500)
setTimeout(()=>{ ce.removeAllListeners("test"); },1500)
|
fs
- 异步方法的最后一个参数都是一个回调函数。
- 传给回调函数的参数取决于具体方法,但回调函数的第一个参数都会保留给异常。 如果操作成功完成,则第一个参数会是
null 或 undefined
- 当使用同步方法时,任何异常都会被立即抛出。 可以使用
try/catch 来处理异常,或让异常向上冒泡
const fs = require("fs");
fs.readFile("./fs.js","utf8",(err,data)=>{ if (err) throw err; console.log(data); });
const data = fs.readFileSync("./path.js","utf8"); console.log(data)
|
const fs = require("fs");
fs.writeFile("./write.js","This is a test",{encoding:"utf8"},err=>{ if (err) throw err;
console.log("done"); });
|
const fs = require("fs");
fs.stat("./fs.js",(err,stats)=>{ if (err) { console.log("文件不存在"); return; };
console.log(stats.isFile()) console.log(stats.isDirectory())
console.log(stats)
})
|
const fs = require("fs");
fs.rename("./write.js","test.js",err=>{ if (err) throw err;
console.log("done"); })
|
const fs = require("fs");
fs.unlink("./test.js",err=>{ if (err) throw err; console.log("done"); })
|
const fs = require("fs");
fs.readdir("./",(err,files)=>{ if (err) throw err; console.log(files);
})
|
const fs = require("fs");
fs.mkdir("test",err=>{});
|
const fs = require("fs");
fs.rmdir("./test",err=>{});
|
const fs = require("fs");
fs.watch("./",{ recursive: true },(eventType,filename) => { console.log(eventType, filename) })
|
const fs = require("fs");
const rs = fs.createReadStream("./fs.js");
rs.pipe(process.stdout)
|
const fs = require("fs");
const ws = fs.createWriteStream("./test5.js");
const time = setInterval(()=>{ const num = parseInt(Math.random() * 10);
if (num < 7) { ws.write(num + ""); } else { clearInterval(time); ws.end(); } },200)
ws.on("finish", () => { console.log("done!"); })
|
异步解决方案
const fs = require("fs"); const promisify = require("util").promisify;
const read = promisify(fs.readFile);
read("./callback.js").then(data=>{ console.log(data.toString()); }).catch(ex=>{ console.log(ex) })
async function test() { try { const content = awit read("./callback.js"); console.log(content.toString()) } catch (ex) { console.log(ex) } } test()
|