Node.js基础使用(Path,Buffer,fs)
Path
const path = require('path')
console.log(__filename)
// 获取路径基础名称,最后一部分
/**
* 返回的就是接收路径当中的最后一部分
* 第二个参数表示扩展名,如果没有设置就返回完整文件名带后缀
* 第二个参数作为后缀时,如果没有在当前路径中被匹配到,那么就会忽略
* 处理目录路径的时候如果结尾处有路径分隔符,则也会被忽略掉
*/
console.log(path.basename(__filename))
console.log(path.basename(__filename,'.js')) // 第二个可选参数,匹配后缀,有就显示文件名称,没有就反正完整文件名
console.log(path.basename(__filename,'.css'))
console.log(path.basename('/a/b/c')) // 返回path路径最后一部分
// 获取路径目录名(路径)
/**
* 返回路径中最后一个部分的上一层目录所在路径
*/
console.log(path.dirname(__filename))
console.log(path.dirname('/a/b/c')) // /a/b
console.log(path.dirname('/a/b/c/')) // /a/b
// 获取路径扩展名
/**
* 返回path路径中相应文件的后缀名
* 如果path路径当中存在多个点,它匹配的是最后一个点到结尾的内容
*
*/
console.log(path.extname(__filename)) // .js
console.log(path.extname('/a/b')) // 空
console.log(path.extname('/a/b/index.html.js.css')) // .css
console.log(path.extname('/a/b/index.html.js.')) // .
// 解析路径
/**
* 接收一个路径,返回一个对象,包含不同的信息
* root dir base ext name(最后一部分名称)
*/
const obj = path.parse('a/b/c/index.html')
// {
// root: '',
// dir: 'a/b/c',
// base: 'index.html',
// ext: '.html',
// name: 'index'
// }
const obj1 = path.parse('a/b/c/') // { root: '', dir: 'a/b', base: 'c', ext: '', name: 'c' }
const obj2 = path.parse('a/b/c') // { root: '', dir: 'a/b', base: 'c', ext: '', name: 'c' }
const obj3 = path.parse('./a/b/c') // { root: '', dir: './a/b', base: 'c', ext: '', name: 'c' }
// 序列化路径
const obj4 = path.parse('./a/b/c')
console.log(path.format(obj4)) // ./a/b\c
// 判断当前路径是否为绝对路径
console.log(path.isAbsolute('foo')) // false
console.log(path.isAbsolute('/foo')) // true
console.log(path.isAbsolute('///foo')) // true
console.log(path.isAbsolute('')) // false
console.log(path.isAbsolute('.')) // false
console.log(path.isAbsolute('../bar')) // false
// 拼接路径
console.log(path.join('a/b','c','index.html')) // a\b\c\index.html
console.log(path.join('/a/b','c','index.html')) // \a\b\c\index.html
console.log(path.join('a/b','c','../','index.html')) // a\b\index.html
console.log(path.join('a/b','c','./','index.html')) // a\b\c\index.html
console.log(path.join('a/b','c','','index.html')) // a\b\c\index.html
console.log(path.join('')) // . 当前工作目录
// 规范化路径
console.log(path.normalize('a/b/c/d')) // a\b\c\d
console.log(path.normalize('a///b/c../d')) // a\b\c..\d
console.log(path.normalize('a//\\b/c\\/d')) // a\b\c\d
console.log(path.normalize('a//\b/c\\/d')) // a\c\d 反斜杠后字母具有特殊意义
console.log(path.normalize('')) // .
// 绝对路径
console.log(path.resolve()) // 打印当前目录
console.log(path.resolve('index.html')) // 打印当前目录/index.html 最常用写法
console.log(path.resolve('a','b')) // 当前目录\a\b
/**
* resolve([from],to) 把to部分拼接为绝对路径,如果拼接完并不是一个绝对路径,
* 那就把当前工作目录加上,让他成为一个绝对路径。from
*/
console.log(path.resolve('/a','b')) // D:\a\b 这里 '/a' 'b'成为了to
console.log(path.resolve('a','/b')) // D:\b 这里a被忽略, '/b'成为了to
console.log(path.resolve('/a','/b')) // D:\b 这里 '/a'被忽略 '/b'成为了to
Buffer
Buffer让Js可以操作二进制全局变量,无须require的一个全局变量实现nodejs平台下的二进制数据操作不占据V8堆内存大小的内存空间内存的使用由Node控制,由v8的GC回收一般配合Stream流使用个,充当数据缓冲区
alloc 创建指定字节大小的bufferallocUnsafe 创建指定大小的buffer(不安全)from 接收数据,创建buffer
const b1 = Buffer.alloc(10); // 单位是字节
console.log(b1); // <Buffer 00 00 00 00 00 00 00 00 00 00>
const b2 = Buffer.allocUnsafe(10);
console.log(b2); // <Buffer 00 00 00 00 00 00 00 00 00 00>
const b3 = Buffer.from("中");
console.log(b3); // <Buffer e4 b8 ad> 16进制 utf-8 一个汉字三个字节
const b4 = Buffer.from([1, 2, 3]);
console.log(b4); // <Buffer 01 02 03>
const b5 = Buffer.from([1, 2, "中"]);
console.log(b5); // <Buffer 01 02 00>
const b6 = Buffer.from([0xe4, 0xb8, 0xad]);
console.log(b6, b6.toString()); // <Buffer e4 b8 ad> 中
const a1 = Buffer.alloc(3);
const a2 = Buffer.from(a1); // 空间并非共享
console.log(a1, a2); // <Buffer 00 00 00> <Buffer 00 00 00>
a1[0] = 1;
console.log(a1, a2); // <Buffer 01 00 00> <Buffer 00 00 00>
fill 使用数据填充bufferwrite 向buffer中写入数据toString 从buffer中提取数据slice 截取bufferindexOf 在buffer中查找数据copy 拷贝buffer中数据
let buf = Buffer.alloc(6);
buf.fill("123", 1, 3); // 第二个参数是填充开始下标位置,第三个代表结束位置,这个位置取不到
console.log(buf, buf.toString()); // <Buffer 31 32 33 31 32 33> 123123 ,长度不够就填充,超出就截取
buf.fill(123)
console.log(buf, buf.toString()); // <Buffer 7b 7b 7b 7b 7b 7b> {{{{{{ 7b专uft-8编码是{
buf.write("123", 1, 4); // 第二个参数是开始位置,第三个参数为长度
console.log(buf, buf.toString()); // <Buffer 31 32 33 00 00 00> 123
buf = Buffer.from("默认值");
console.log(buf, buf.toString()); // <Buffer e9 bb 98 e8 ae a4 e5 80 bc> 默认值
console.log(buf, buf.toString("utf-8", 3, 9)); // <Buffer e9 bb 98 e8 ae a4 e5 80 bc> 认值 ,第二个参数表示开始下标,第三个表示结束位置
buf = Buffer.from("默认值");
let b1 = buf.slice(); // 第一第二个参数表示开始位置和结束位,顾头不顾尾 ,如果是负数,表示从尾部开始,-3打印出来“值”
console.log(b1, b1.toString()); // <Buffer e9 bb 98 e8 ae a4 e5 80 bc> 默认值 ---从头截取到尾部
buf = Buffer.from("默认值,阿西洛夫");
console.log(buf, buf.indexOf("阿")); // <Buffer e9 bb 98 e8 ae a4 e5 80 bc 2c e9 98 bf e8 a5 bf e6 b4 9b e5 a4 ab> 10 ----中文占三个字节,所以阿字下标是10
console.log(buf, buf.indexOf("啊", 4)); // <Buffer e9 bb 98 e8 ae a4 e5 80 bc 2c e9 98 bf e8 a5 bf e6 b4 9b e5 a4 ab> -1
let b1 = Buffer.alloc(6);
let b2 = Buffer.from("前端");
b2.copy(b1); // b2拷贝到b1里面
console.log(b1.toString(), b2.toString()); // 前端 前端
let b1 = Buffer.alloc(6);
let b2 = Buffer.from("前端");
b2.copy(b1); // b2拷贝到b1里面 ,第二个参数表示拷贝开始位置,第三个参数从源buffer读取开始位置,第四个参数表示源buffer读取结束位置,顾头不顾尾
console.log(b1.toString(), b2.toString()); // 前端 前端
let b1 = Buffer.from("前端");
let b2 = Buffer.from("性能");
let b = Buffer.concat([b1, b2]);
console.log(b, b.toString()); // <Buffer e5 89 8d e7 ab af e6 80 a7 e8 83 bd> 前端性能
let b3 = Buffer.concat([b1, b2], 9);
console.log(b3, b3.toString()); // <Buffer e5 89 8d e7 ab af e6 80 a7> 前端性
let b4 = Buffer.alloc(3);
console.log(Buffer.isBuffer(b4)); // true
对Buffer实现数组的split操作
// buffer长度创建后是固定的,实现一个split方法
ArrayBuffer.prototype.split = function (sep) {
let len = Buffer.from(sep).length;
let result = [];
let start = 0;
let offset = 0;
while ((offset = this.indexOf(sep, start) !== -1)) {
result.push(this.slice(start, offset));
start = offset + len; // 更新start位置
}
result.push(this.slice(start))
return result;
};
let buf = "小明喜欢吃馒头,吃水果,吃米饭吃";
let bufArr = buf.split("吃");
console.log(bufArr); // [ '小明喜欢', '馒头,', '水果,', '米饭', '' ]
buffer应用场景图片base64编码转换
const fs = require('fs');
const path = require('path');
// function to encode file data to base64 encoded string
function base64_encode(file) {
let bitmap = fs.readFileSync(file);
return Buffer.from(bitmap).toString('base64');
}
// function to create file from base64 encoded string
function base64_decode(base64str, file) {
let bitmap = Buffer.from(base64str, 'base64');
fs.writeFileSync(file, bitmap);
}
let base64str = base64_encode(path.join(__dirname, './a.png'));
console.log(base64str);
base64_decode(base64str, path.join(__dirname, 'copyA.png'));
文件读取buffer有乱码的问题解决方案1
// 可读流有⼀个设置编码的⽅法setEncoding():
默认情况下没有设置字符编码,流数据返回的是 Buffer 对象。 如果设置了字符编码,则流数据返
回指定编码的字符串
// fs.createReadStream 的 options 中 highWaterMark默认是64k
const rs = fs.createReadStream(path.join(__dirname, '1.txt'),
let rs = fs.createReadStream('test.md', {highWaterMark: 11});
rs.setEncoding('utf8');
解决方案2
const res = fs.createReadStream(path.join(__dirname, '1.txt');
// 将⼩Buffer 拼接成⼤Buffer 对象
let chunks = [];
let size = 0;
res.on('data', function (chunk) {
chunks.push(chunk);
size += chunk.length;
});
res.on('end', function () {
let buf = Buffer.concat(chunks, size);
let str = iconv.decode(buf, 'utf8'); // 累加buffer,iconv
console.log(str);
});
FS
Fs基本操作类Fs常用API常见flag操作符
r 可读 w 可写 s 同步 + 执行相反操作 x排它操作 a 追加操作
代码示例
const fs = require("fs");
// readFile
fs.readFile(path.resolve("file.txt"), "utf-8", (err, data) => {
console.log(err); // null ,路径错误就会打印错误信息
console.log(data); // 123
});
fs.writeFile("data.txt", "hello node.js", (err) => {
if (!err) {
fs.readFile("data.txt", "utf-8", (err, data) => {
console.log(data); // hello node.js
});
}
});
fs.writeFile("data.txt", "hello node.js", (err) => { // writeFile覆盖写操作
if (!err) {
fs.readFile("data.txt", "utf-8", (err, data) => {
console.log(data); // hello node.js
});
}
});
fs.writeFile("data.txt", "abcd" ,{
mode:438,
flag:'r+', // 这个模式不会默认清空文件
encoding:'utf-8'
}, (err) => { // writeFile覆盖写操作
if (!err) {
fs.readFile("data.txt", "utf-8", (err, data) => {
console.log(data); // abcdo node.js
});
}
});
// 追加写入
fs.appendFile('data.txt','前端',(err)=>{
console.log("write")
})
fs.copyFile('data.txt','dataCopy.txt',(err)=>{
console.log("copy success")
})
fs.watchFile('data.txt',{interval:20},(cur,pre)=>{ // 每20毫秒监控一次
if(cur.mtime !== pre.mtime){
console.log("file modify") // 修改时会有打印
fs.unwatchFile('data.txt') // 取消监控
}
})
转载自:https://segmentfault.com/a/1190000041781696