node.js常用方法总结(fs模块、path模块、IO流、net模块、http模块)

关于路径(获取一个绝对路径)

node中除了require的路径是相对于当前文件的路径,其他的都是相对于命令行的路径

const fs = require("fs");
const path = require("path");
path.resolve(__dirname,获取的文件的相对路径);  //可以获取这个文件的绝对路径

node中的回调模式

//前面写的是传过去的值content是完成的内容。err是错误
fs.readFile(filename, (*err*, *content*) => {
 console.log(*content*);
});

Buffer转换成字符串

fs.readFile(filename, (*err*, *content*) => {
 console.log(*content.toString("utf-8")*);
});

关于fs

关于flags

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QZsRgKId-1664767833971)(image-20220509171310229.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-82lS6AIf-1664767833973)(image-20220509171331459.png)]

fs.readFile()读取一个文件

可以传递三个参数第一个是路径,第二个是编码方式,第三个是回调函数,

如果写了编码方式传过来的就不是一个Buffer,就是编码过后的东西

读取文件内容

fs.readFile('/etc/passwd', 'utf8', callback);
fs.writeFile()写入一个文件

如果文件不存在就会新建一个,如果目录不存在就会报错

async function test() {
  await fs.promises.writeFile(filename, "dsajkldsa", {
    flag: "a",
  });
  //最后一个表示配置{flag:“a”}表示追加
  fs.readFile(filename, (err, content) => {
    console.log(content.toString("utf-8"));
  });
}
fs.stat()获取文件状态

获取传入文件的状态

也可以传入目录

目录的size为0,目录记录一个指针,指针指向其中文件的地址,打开目录其实是通过指针找到文件的位置

async function test() {
  const status = await fs.promises.stat(filename);
  console.log(status);
}

test();
//输出结果
Stats {
  dev: 1544704498,
  mode: 33206,
  nlink: 1,
  uid: 0,
  gid: 0,
  rdev: 0,
  blksize: 4096,
  ino: 7036874417856700,
  size: 47680,
  blocks: 96,
  atimeMs: 1651996271195.6572,
  mtimeMs: 1651718270707.592,
  ctimeMs: 1651718270707.592,
  birthtimeMs: 1651995922591.119,
  atime: 2022-05-08T07:51:11.196Z,
  mtime: 2022-05-05T02:37:50.708Z,
  ctime: 2022-05-05T02:37:50.708Z,
  birthtime: 2022-05-08T07:45:22.591Z
}

fs.readdir()获取文件子目录

获取文件中的子目录

async function test() {
  const dirname = path.resolve(__dirname, "./readme");
  const paths = await fs.promises.readdir(dirname);
  console.log(paths);
}

test();
//输出内容
[ '1.text', 'G.jpg', 'Gf.jpg' ]
fs.mkdir()创建一个目录

可以使用fs.writeFile()创建一个文件

创建一个目录

 async function test() {
   for (let i = 0; i < 5; i++) {
     const dirname = path.resolve(__dirname, `./readme/${i}`);
     await fs.promises.mkdir(dirname);
   }
 }

 test();
判断一个一个目录是否存在
async function exits(filename) {
  try {
    await fs.promises.stat(filename);
    return true;
  } catch (error) {
    if (error.code === "ENOENT") {
      return false;
    }
    throw error;
  }
}
async function test() {
  const dirname = path.resolve(__dirname, "./readme/7");
  const result = await exits(dirname);
  if (result) {
    console.log("目录已存在");
  } else {
    console.log("目录不存在,已经帮你创建");
    fs.promises.mkdir(dirname);//c
  }
}

test();
fs.unlink()删除一个文件
删除一个文件
fs.unlink(filename)

关于path

path.basename()获得文件名

得到这个当前的文件名

async function test() {
  const basename = path.basename("/foo/bar/baz/asdf/quux.html");
  // Returns: 'quux.html'
  console.log(basename);
}
path.sep 操作系统分隔符

path.sep就是当前操作系统的分隔符

console.log(path.sep);
/
path.delimiter 系统之间的分隔符

path.delimiter是系统之间的分隔符

console.log(path.delimiter);
:
path.dirname()获得当前目录

获取当前的目录

async function test() {
  const dirname = path.dirname("/foo/bar/baz/asdf/quux");
  console.log(dirname);
  ///foo/bar/baz/asdf
}
path.extname()获取当前的文件类型(.js、.html)

获取当前的文件类型

async function test() {
  const extname = path.extname("/foo/bar/baz/asdf/quux.html");
  console.log(extname);
  //.html
}
path.join()把所有传进去的路径合起来

把所有传进去的路径合起来

path.join('/foo', 'bar', 'baz/asdf', 'quux', '..');
// Returns: '/foo/bar/baz/asdf'
path.resolve()把传进去的路径合起来

把传进去的路径合起来

path.resolve('/foo/bar', './baz');
// Returns: '/foo/bar/baz'

关于IO流

fs.createReadStream()创建一个可读流

创建一个可读流

//接收两个参数
//文件路径
//配置
const rs = fs.createReadStream(filename, {
  encoding: "utf-8",
  highWaterMark: 1,//每一次读取的数量,如果encoding===null,就是一个字符,如果是utf-8就是一个文字字符
  autoClose:true //完成时自动关闭
});
//使用on函数注册事件
//可以触发的事件
//open  打开之后触发
//error  文件出错了(一般是路径写错了)
//close   文件关闭后触发
//data    只有注册了这个事件才会真正开始读取内容,读取到内容后触发,返回读取到的内容
//end     d
//如果要读取全部的数据的话,不如直接用fs.readFile()
//rs.pause()  暂停读取  会触发pause事件
//rs.resume()  恢复读取  会触发resume事件
rs.on("data",chunk=>{
  console.log("读取到了文件"+chunk)
}) //只有运行了这个才会开始读取文件不然就不会读取文件 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TXIs898e-1664767833974)(image-20220509193434726.png)]

fs.createWriteStream()创建一个写入流
const path = require("path");
const fs = require("fs");

const filename = path.resolve(__dirname, "./abc.text");

const ws = fs.createWriteStream(filename, {
  flags: "a",  //如何对文件进行操作
  highWaterMark: 2,  //每一次读取的数量,如果encoding===null,就是一个字符,如果是utf-8就是一个文字字符
  autoClose: true,
  start:1  //起始位置
});

const data = "123456";
ws.write(data);//写入一些数据
//可以穿字符串也可以传buffer,返回一个布尔值(返回的时true的话表示写入通道没有被tian),当写入队列清空时,会触发drain事件

ws.on("open", () => {
  console.log("写入开始了");
});
// 注册事件ws.on('事件',callback)
//open事件
//error事件
//close事件
ws.on("close", () => {
  console.log("写入结束了");
});
ws.end();

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9rxJHVNN-1664767833974)(image-20220509183123451.png)]

ws.write(data)会返回一个布尔值(磁盘的写入速度和内存比是很慢的)当写入通道没满时ws.write(data)会返回true,后面的写入就不用排队可以直接写入,反之就是写入通道被占满了,接下来的数据会进入写入队列

背压问题:

​ 造成原因:内存速度太快了,但是磁盘写入很慢,很多要写入的东西都积压在写入队列,造成很大的内存空间占用。因为写入队列是内存中的数据,是有限的,可以使用drain事件来解决这个问题,这个事件会在当原来是满的时候,当写入队列清空时,会触发drain事件,如果本来就没有满,就算清空了也不会触发事件

防止背压的写入方法

async function method2() {
  const from = path.resolve(__dirname, "./abc.text");
  const to = path.resolve(__dirname, "./cba.text");
  const rs = fs.createReadStream(from);
  const ws = fs.createReadStream(to);
  (rs.on("data", (chunk) => {
    const flag = ws.write(chunk);
    if (!flag) {
      rs.pause();
    }
  });
  ws.on("drain", () => {
    rs.resume();
  });)//可以简写为rs.pipe(ws)
}
//直接使用rs.pipe(ws)就可以完成上面的操作

net模块(通信模块)

利用net模块已经进行进程之间的通信(IPC协议)

前端主要是网络协议(TCP/IP协议 )

创建客户端

net.createConnection(options[, connectListener])

const net = require("net");
//第一个参数是配置项,第二个就是连接成功之后的回调函数
net.createConnection(
  {
    host: "xxx.xxx.xxx",
    port: 80,
  },
  () => {
    console.log("连接成功");
  }
);

截取请求头内容
function parseResponse(response) {
  const index = response.indexOf("\r\n\r\n"); //获取请求头的结束index
  const head = response.substring(0, index); //截取请求头部分
  const body = response.substring(index + 2); //截取请求体部分
  const headParts = head.split("\r\n"); //把请求头以换行作为分隔符拆分为数组
  const headerArray = headParts.slice(1).map(str => {
    return str.split(":").map(s => s.trim());
  });
  const header = headerArray.reduce((a, b) => {
    a[b[0]] = b[1];
    return a;
  }, {});
  return {
    header, //请求头
    body: body.trimStart()  //请求体
  };
}
创建一个服务器
const net = require("net");
const server = net.createServer();

server.listen(9258); //监听某个端口
server.on("listening", () => {}); //开始监听端口后触发的事件
server.on("connection", (socket) => {
  socket.on("data", function (thunk) {
    console.log(thunk.toString("utf-8"));
    //这里有个http响应格式规范
    //响应头的响应体换两行
    socket.write(`HTTP/1.1 200 OK

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      div {
        width: 0;
        height: 0;
        border: 10px solid red;
        border-right-color: transparent;
        border-bottom: transparent;
        border-left: transparent;
        transform: rotate(45deg);
      }
    </style>
  </head>
  <body>
    <div></div>
  </body>
</html>
`);
    socket.end();
  });
  socket.on("close", function () {
    console.log("连接关闭了");
  });
}); //在某个连接到来时,触发的事件

传输一个图片
const net = require("net");
const server = net.createServer();
const fs = require("fs");
const path = require("path");

server.listen(9258); //监听某个端口
server.on("listening", () => {}); //开始监听端口后触发的事件
server.on("connection", (socket) => {
  socket.on("data", async function (thunk) {
    //这里有个http响应格式规范
    //响应头的响应体换两行
    //传输一个图片
    const filename = path.resolve(__dirname + "/1.jpg");
    console.log(filename);
    const bodyBuffers = await fs.promises.readFile(filename);
    const headerBuffers = Buffer.from(`HTTP/1.1 200 OK
Content-Type:image/jpeg

`,
      "utf-8"
    );
    const result = Buffer.concat([headerBuffers, bodyBuffers]);
    socket.write(result);
    socket.end();
  });
  socket.on("close", function () {
    console.log("连接关闭了");
  });
}); //在某个连接到来时,触发的事件

http模块

发送请求(post/get)
const http = require("http");
const request = http.request(
  "http://yuanjin.tech:5005/api/movie",
  {
    method: "POST",
  },
  (resp) => {
    let result = "";
    console.log("响应的请求头", resp.headers);
    resp.on("data", (thunk) => {
      result += thunk;
    });
    resp.on("end", () => {
      console.log(JSON.parse(result));
    });
  }
);
request.write("a=1&b=2"); //发送post请求携带的参数(写在消息体里面)  get的话直接发就行
//这个request对象就是一个可写流
request.end(); //end之后才会真正的获取相应   因为请求中没有两次换行所以服务器认为还有东西没有发送,所以调用end之后才会真正的获取响应(表示消息体结束)

创建一个服务器
const http = require("http");
const url = require("url");

const server = http.createServer((req, resp) => {
  //req incomingMessage   (发送请求过来的那个对象)
  //res serverResponse   (用于响应的)
  console.log("请求路径", url.parse(req.url)); //利用url模块解析发送请求的地址
  console.log("请求方法", req.method);
  console.log("请求头", req.headers);
  let body = "";
  req.on("data", (thunk) => {
    //请求体要从流里面读,因为可能请求的东西很多,放在配置里面就会占用很多内存,所以要一块一块传(配置里面的东西也都会放在内存里)
    body += thunk.toString("utf-8");
  });
  req.on("end", () => {
    console.log("请求体", body);
  });
  resp.setHeader("a", "1"); //设置响应头
  resp.setHeader("b", "2");
  resp.write("hello"); //响应的数据
  resp.end(); //一定要写    结束响应
});
server.listen(9527);

server.on("listening", () => {
  console.log("server listening 9527");
});

搭建一个静态资源服务器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YdzDaP9y-1664767833975)(image-20220609142640461.png)]

const http = require("http");
const URL = require("url");
const path = require("path");
const fs = require("fs");

async function getStat(filename) {
  try {
    return await fs.promises.stat(filename);
  } catch (error) {
    return null;
  }
}
/**
 *
 * @param {*} url
 * @returns 得到文件内容
 */
async function getFileContent(url) {
  const urlObj = URL.parse(url);
  let filename;
  filename = path.resolve(__dirname, "public", urlObj.pathname.substring(1)); //如果不用substring的话就会定位到根目录,因为urlObj.pathname有一个/
  // console.log(urlObj);
  let stat = await getStat(filename);
  if (!stat) {
    //文件不存在
    console.log("文件不存在");
    return null;
  } else if (stat.isDirectory()) {
    //文件是一个目录
    console.log("自动添加index.html");
    filename = path.resolve(
      __dirname,
      "public",
      urlObj.pathname.substring(1),
      "index.html"
    );
    console.log(filename);
    stat = await getStat(filename);
    if (!stat) {
      console.log("文件不存在");
      return null;
    } else {
      console.log("正常文件");
      console.log(filename);
      return await fs.promises.readFile(filename); //返回文件建议使用流的方式返回
    }
  } else {
    console.log("正常的文件");
    console.log(filename);
    return await fs.promises.readFile(filename); //返回文件建议使用流的方式返回
  }
}

async function handler(req, resp) {
  const info = await getFileContent(req.url);
  if (info) {
    resp.write(info);
  } else {
    resp.statusCode = 404;
    resp.write("Resource is not exist");
  }
  resp.end();
}

const server = http.createServer(handler);

server.listen(6100);
server.on("listening", () => {
  console.log("server listening 6000");
});

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值