您现在的位置是:首页 > 正文

【nodejs基础】I/O,Buffer,http模块,stream

2024-02-26 00:57:36阅读 7

I/O处理

关于 I/O ,有一个很经典的响水壶解释。

  • 隔壁王大爷有个水壶,王大爷经常用它来烧开水。
  • 同步阻塞:王大爷把水壶放到火上烧,然后啥也不干在那等,直到水开了王大爷再去搞别的事情。
  • 同步非阻塞:王大爷觉得自己有点憨,不打算等了。把水壶放上去之后大爷就是去看电视,时不时来瞅一眼有没有开。
  • 异步阻塞:王大爷去买了个响水壶,他把响水壶放在火上,然后也是等着水开,水开的时候水壶会发出声响。
  • 异步非阻塞:王大爷又觉得自己有点憨,他把响水壶放在火上然后去看电视,这时他不用是不是来瞅一眼,因为水开 的时候水壶会发出声音通知大爷。
  • 上面四个例子里,阻塞非阻塞说明的是大爷的状态,同步非同步说明的是水壶的调用姿势。水壶能在烧好的时候主动响起,就等同于我们异步的定义,能在结束时通知主线程并且回调。所以异步一般配合非阻塞,才能发挥其作用。

promisify

  • 使用 promisify 可以让一个回调函数风格的异步方法变成 promise 风格。
  • 利用一个自执行函数,就可以使用 async await 风格书写代码。
(async () => {
  const fs = require("fs")
  // 使用 promisify 可以让一个回调函数形式的异步方法 变成 promise 形式 从而可以使用 async await
  const { promisify } = require("util")
  // 将 fs.readFile 方法 包装成 promise
  const readFile = promisify(fs.readFile)
  // 读取的是个 buffer 对象 ,是 js 用来描述二进制的东西
  const data = await readFile("./test.js")
  // toString方法解析字符串
  console.log("data", data.toString())
})()

Buffer

  • 读取数据类型为 Buffer
  • 用于在 TCP 流、文件系统操作、以及其他上下文中与八位字节流进行交互。 八位字节组成的数组,可以有效的在 JS 中存储二进制数据。
// 创建一个长度为 10 字节以 0 填充的 Buffer
const buf1 = Buffer.alloc(10)
console.log('🚀🚀~ buf1:', buf1);

// 创建一个 Buffer 包含 ascii.
const buf2 = Buffer.from("a")
console.log('🚀🚀~ buf2:', buf2);

// 创建Buffer包含UTF-8字节 
// UFT-8:一种变长的编码方案,使用 1~6 个字节来存储; 
// UFT-32:一种固定长度的编码方案,不管字符编号大小,始终使用 4 个字节来存储; 
// UTF-16:介于 UTF-8 和 UTF-32 之间,使用 2 个或者 4 个字节来存储,长度既固定又可变。
const buf3 = Buffer.from('中')
console.log('🚀🚀~ buf3:', buf3);

// 写入 Buffer 数据 
buf1.write('hello'); 
console.log(buf1); 

// 读取 Buffer 数据 
console.log(buf3.toString());

// 合并 Buffer 数据 
const buf4 = Buffer.concat([buf2, buf3])
console.log('🚀🚀~ buf4:', buf4, buf4.toString());

http模块

  • writeHead 可以同时书写 statusCodesetHeader
  • 判断 req.headers.accept 是否包含 image/* 可以判断是不是请求图片。
const http = require("http")
const fs = require("fs")
// 创建服务
const server = http.createServer((req, res) => {
  const { url, method, headers } = req
  if (url === '/' && method === 'GET') {
    fs.readFile("./src/03-http/index.html", (err, data) => {
      if (err) {
        res.writeHead(500, { 'Content-Type': 'text/plain;charset=utf-8' })
        res.end("500 服务器错误")
        return
      }
      res.statusCode = 200
      res.setHeader('Content-Type', 'text/html')
      res.end(data)
    })
  }
  else if (url === '/getUser' && method === 'GET') {
    res.writeHead(200, { 'Content-Type': 'application/json' })
    res.end(JSON.stringify({ name: "warbler" }))
  }
  // Accept代表发送端(客户端)希望接受的数据类型。 比如:Accept:text/xml; 代表客户端希望 接受的数据类型是xml类型。 
  // Content-Type代表发送端(客户端|服务器)发送的实体数据的数据类型。 比如:ContentType:text/html; 代表发送端发送的数据格式是html。 
  // 二者合起来, Accept:text/xml; Content-Type:text/html ,即代表希望接受的数据类型是xml格 式,本次请求发送的数据的数据格式是html。
  else if (method === 'GET' && headers.accept.indexOf("image/*") !== -1) {
    // 统一描述所有的图片请求
    fs.createReadStream(`./src/03-http/${url}`).pipe(res)
  }
  else {
    res.statusCode = 404
    res.setHeader('Content-Type', 'text/plain;charset=utf-8')
    res.end("404 页面未找到")
  }
})
server.listen(3000, () => {
  console.log('🚀🚀~ sever at 3002');
})

stream

const fs = require("fs")

// 读流
const rs = fs.createReadStream('./src/04-stream/main.jpg')

// 写流
const ws = fs.createWriteStream('./src/04-stream/main2.jpg')

// 连接导管 可以复制图片到指定目录
rs.pipe(ws)

参考资料

开课吧全栈架构师课程

网站文章

  • mavend jar包报错,导包导不进去,手动导包;代码编译没错但运行报错: “程序包xxx不存在“的问题

    mavend jar包报错,导包导不进去,手动导包;代码编译没错但运行报错: “程序包xxx不存在“的问题

    导包导不进去,pom文件中 依赖直接是红色有的时候明明本地仓库下载了,可还是项目中出现令人厌倦的下红线idea非得报错,我本地仓库中有此下载的包甚至idea中可以在外部库中找到,maven编译和install都没报错,可运行此相关方法报错了。

    2024-02-26 00:57:21
  • php-fpm进程数设置多少合适

    在我们做php高并发下的优化的时候,涉及到一个问题,就是fpm进程数设置多少合适,在有的文章中推荐设置为n或者n×2(n为cpu数量)有的文档中推荐按照可用内存/30m (30m为fpm每个进程内存)

    2024-02-26 00:57:07
  • Zookeeper的分布式锁例子(Curator)

    Zookeeper的分布式锁例子(Curator)

    2024-02-26 00:56:55
  • 服务器显示oplen,deloplen.com

    Domain Name: DELOPLEN.COMRegistry Domain ID: 2374424842_DOMAIN_COM-VRSNRegistrar WHOIS Server: whois...

    2024-02-26 00:56:11
  • 达梦数据库入门 - 零基础到入门 - 达梦云适配中心

    达梦数据库入门 - 零基础到入门 - 达梦云适配中心

    前言:越来越多的同学或基于工作需求,或基于兴趣爱好上了解到了国产达梦数据库,但往往再想要学习新的知识的时候不知道该从何处入手,网上查询相关资料的话杂乱无章,往往让会令自己更加迷茫于该怎么入手去学习达梦...

    2024-02-26 00:56:03
  • position定位

    回顾 1.元素分类:块级、行内元素 2.img和input属于行内块、置换元素 3.display: block块 inline行内 inline-block行内块 none无 定位position ...

    2024-02-26 00:55:25
  • 软件测试---软件性能测试和可靠性测试

    1.软件性能测试的基本概念 软件的性能是软件的一种非功能特性,它关注的不是软件是否能够完成特定的功能,而是软件在完成该功能时展示出来的及时性。 (1)软件性能的指标 1)响应时间:是指系统对请求作出响应的时间,并且这个时间被人们的接收程度是随着系统的不同而不同的(一个游戏相应3秒无法忍受,一个编译程序编译3分钟也是可以接受的) 2)系统相应时间和应用延迟时间:前面的响应时间...

    2024-02-26 00:55:15
  • ESP32学习笔记: 使用NVS存储数据的嵌入式应用

    ESP32学习笔记: 使用NVS存储数据的嵌入式应用

    在嵌入式系统开发中,数据的存储和管理是一个重要的任务。本文将介绍如何在ESP32上使用NVS存储数据,并提供相应的源代码示例。通过上述步骤,我们可以在ESP32上使用NVS轻松地存储和检索数据。NVS...

    2024-02-26 00:55:02
  • 我的Spring学习经验 最新发布

    引言 Spring是一个开源的Java框架,它提供了一种简化企业级应用开发的方式。我在学习过程中积累了一些经验,希望能与大家分享。 一、学习Spring的具体内容 学习Spring的具体内容通常涵盖以...

    2024-02-26 00:54:29
  • 上硅谷mysql笔记基础视频03笔记

    原则1 所选择的类型越简单越好,能保存数字的类型越小越好;2 较短的文本: char varchar(M)M:最多的字符数char:固定的长度;varchar:可变的长度;har:性能高:固定使用v...

    2024-02-26 00:54:14