node学习:包package,Buffer缓存和fs文件系统

 

1. 包package

      包实际上是一个压缩文件,解压以后还原为目录。包里存放的是模块。符合规范的目录如下。包结构:

  • package.json   描述文件(必有)
  • bin    可执行二进制文件
  • lib    js代码
  • doc    文档
  • test    单元测试

      包描述文件用于表达非代码相关的信息,是一个JSON格式的文件--package.json(不能写注释),位于包的一级目录下,打开包即可看见该文件。

2. npm (Node Package Manager:node包管理器)

      对于node而言,NPM帮助其完成第三方模块的发布、安装和依赖等。借助NPM,Node与第三方模块之间形成了很好的生态系统。

      npm 命令

  • npm -v        查看版本
  • npm -version        查看所有版本
  • npm search 包名       搜索模块包
  • npm init      初始化npm
  • npm install 包名 或 npm i 包名      在当前目录下安装包
  • npm install 包名 --save  或   npm i 包名 -S       安装包并添加到依赖
  • npm installnpm i       下载当前项目所依赖的包
  • npm install 包名 -g        全局模式安装包
  • npm remove 包名  或 npm r 包名       删除包
  • npm run build        打包
  • npm cache clean --firce         清除缓存

3. cnpm 

      CNPM 是中国 npm 镜像的客户端。要使用cnpm之前,要先安装。cnpm 支持所有的npm命令。

$ npm install cnpm -g --registry=https://registry.npm.taobao.org

       通过npm或cnpm下载的包都放在里node_modules文件夹中,使用前直接通过包名引入即可。node在使用模块名引入模块时,会首先在当前目录的node_modules文件夹中寻找是否含有该模块,如果有直接使用,如果没有会去上一级的node_modules文件夹中继续寻找,知道找到为止,直到找到磁盘的根目录,如果依然没有,则报错。

4. Buffer 缓冲区

      Buffer 的结构与数组很像,操作方法也和数组类似,但并不是数组。数组中不能存储二进制文件,而Buffer就是专门用来存储二进制数据的。使用Buffer不需要引入模块,直接使用即可

      在Buffer中存储的都是二进制。下标结果是二进制以十六进制的形式展示(显示时),因为二进制太长了!

      Buffer的每一个元素的范围是00 - ff  (0 - 255)(00000000 - 11111111),每一个元素都占用一个字节,buffer长度为13,表示strToBuffer占用了13个字节(占用的内存大小)。当字符串中含有中文时,一个汉字占用3个字节。

      Buffer.from(str)  :将一个字符串转化为buffer。可以通过buf.toString()将buffer数据转化为字符串。

// buffer.js
var str = "Hello  Buffer"
var str2 = "Hello  绿萝"
// 转Buffer
var strToBuffer = Buffer.from(str)
var chineseToBuffer = Buffer.from(str2)
console.log(strToBuffer)
console.log(strToBuffer.length, str.length)
console.log(chineseToBuffer)
console.log(chineseToBuffer.length, str2.length)
PS F:\workspace\yanj\RD4006\cssTest\node\buffer> node buffer.js
<Buffer 48 65 6c 6c 6f 20 20 42 75 66 66 65 72>
13 13
<Buffer 48 65 6c 6c 6f 20 20 ef bf bd ef bf bd ef bf bd ef bf bd>
19 11

      通过Buffer.alloc给buffer分配一定的字节空间 (分配的同时,该空间的原有数据会被清空):

// 分配10个字节空间
var buf2 = Buffer.alloc(10)
// var buf2 = new Buffer(10) // 会警告安全性和可用性问题   buffer构造函数不推荐使用  创建一个指定大小的Buffer
buf2[0] = 134;
buf2[1] = 255
buf2[2] = 0xaa
buf2[10] = 15 // buffer的大小一旦确定,则不能修改  buffer的空间一定是连续的
buf2[5] = 360 // 0001 0110 1000
buf2[6] = 104 //      0110 1000
console.log(buf2)
console.log(buf2[2])
console.log(buf2[2].toString(16))
PS F:\workspace\yanj\RD4006\cssTest\node\buffer> node buffer.js
<Buffer 86 ff aa 00 00 68 68 00 00 00>
170
aa

      由结果可以看出,当只分配10个字节的buffer空间时,如果在第buf2[10]的位置修改内容,是无效的。因为buffer的空间是连续的,并且大小一旦确定,就不能修改了。如果可以自加新空间,考虑到下一个位置的内存可能已经被占用了,如果可以被分配其他空位置,会导致一个buffer元素的内容在内存中 的存放位置很多,会很乱。Buffer直接操作内存,这些应该被考虑到。

      如果buffer中的数据超过它的 00-ff 范围怎么办?如buf2[5] 和 buf2[6] 在buffer中的数据是一样的,为什么?因为超过范围的部分会被截掉,只显示范围内的字节。

      buffer的数据只要是数字,在控制台或页面中显示时,输出的一定的十进制。如果想要16进制输出,可以用toString(16)

      通过Buffer.allocUnsafe给buffer分配一定的字节空间 (分配的同时,该空间的原有数据不会被清空,但含有敏感数据):

// buffer.js
var buf5 = Buffer.allocUnsafe(10) 
console.log(buf5)
PS F:\workspace\yanj\RD4006\cssTest\node\buffer> node buffer.js
<Buffer f0 5d f4 34 bb 01 00 00 f0 5d>

5. fs文件系统

      在Node中,与文件系统的交互很重要,服务器的本质就是将本地的文件发送给远程的客户端。Node通过fs模块和文件系统进行交互,该模块提供了一些标准文件访问API来打开、读取、写入文件,以及与其交互。

      要使用fs模块,首先需要对其进行加载require('fs')。fs模块中的所有操作都有两种形式:同步和异步。同步文件系统会阻塞程序的执行,也就是除非操作完毕,否则不会向下执行代码。异步文件系统不会阻塞程序的执行,而是在操作完成时,通过回调函数将结果返回。

5.1 同步文件写入

/*
  fs模块 -- 同步文件写入
  1. 打开文件
     fs.openSync(path[, flags[, mode]], callback)
       - path  要打开文件的路径
       - flags  打开文件要做的操作类型
           r  只读
           w  可写
       - mode  设置文件的操作权限,一般不传
  2. 向文件中写入内容
     fs.writeSync(fd, buffer[, offset[, length[, position]]])
       - fd  文件描述符,需要传递要写入的文件的描述符
       - string  要写入的内容
       - position  写入的起始位置
       - encoding  写入的编码,默认是utf-8
  3. 保存并关闭文件
     fs.closeSync(fd)
       - fd  要关闭的文件的描述符
*/
var fs = require('fs')
var fd = fs.openSync('fs.txt', 'w')
console.log(fd) // 3
fs.writeSync(fd, "this is a pig.", 2)
fs.closeSync(fd)
// fs.txt
this is a pig.

5.2 简单文件写入

  fs.writeFile(file, data[, options], callback)
  fs.writeFileSync(file, data[, options]) // 同步
     - file  要操作的文件的路径,也可以是绝对路径
     - data  要写入的数据
     - options  选项,可以对写入进行一些设置
        - flag  打开状态
     - callback  当写入完成以后执行的函数
// simpleWrite.js
// 引入fs模块
let fs = require('fs')
let simpleWriteStr = 'simple-write: writeFile()'
fs.writeFile('simpleWrite.txt', simpleWriteStr, {flag: "a"}, err => {
  if (!err) {
    console.log('写入成功!')
  }
})
// simpleWrite.txt
我是先写入的内容:simple-write: writeFile()
PS F:\node\fs> node simpleWrite.js
写入成功!

      flag:参数值列表:: 

'r' -   以读取模式打开文件。
'r+' - 以读写模式打开文件。
'rs' - 使用同步模式打开并读取文件。指示操作系统忽略本地文件系统缓存。
'rs+' - 以同步的方式打开,读取 并 写入文件。

注意:这不是让fs.open变成同步模式的阻塞操作。如果想要同步模式请使用fs.openSync()。

'w' - 以读取模式打开文件,如果文件不存在则创建,如果存在则截断
'wx' - 和 ' w ' 模式一样,如果文件存在则返回失败
'w+' - 以读写模式打开文件,如果文件不存在则创建,如果存在则截断
'wx+' - 和 ' w+ ' 模式一样,如果文件存在则返回失败

'a' - 以追加模式打开文件,如果文件不存在则创建
'ax' - 和 ' a ' 模式一样,如果文件存在则返回失败
'a+' - 以读取追加模式打开文件,如果文件不存在则创建
'ax+' - 和 ' a+ ' 模式一样,如果文件存在则返回失败

mode    用于创建文件时给文件制定权限,默认0666

5.3 流式文件写入

      同步、异步、简单文件写入都不适合大文件的写入,性能较差,容易导致内存溢出。

/* 
  fs.createWriteStream(path[, options])
    - 可以用来创建一个可写流
    - path  文件路径
    - options  配置参数
*/
// streamWrite.js
let fs = require('fs')
// 流式文件写入
// 创建一个流
let ws = fs.createWriteStream('streamWrite.txt')
// 可以通过监听流的open和close事件来监听流的打开和关闭
// open是一次性绑定事件  用once绑定
ws.once("open", () => {
  console.log('流打开')
})
ws.once("close", () => {
  console.log('流关闭')
})
// 通过ws向文件中写入输入内容
ws.write('011111111,')
ws.write('022222222,')
ws.write('033333333,')
ws.write('044444444,')
ws.write('055555555.')
// ws.close()
ws.end()

// streamWrite.txt
011111111,022222222,033333333,044444444,055555555.
PS F:\node\fs> node streamWrite.js
流打开
流关闭

对于绑定事件有些可以说的:  

      on(事件字符串, 回调函数)
           - 可以为对象绑定一个事件
      once(事件字符串, 回调函数)
           - 可以为对象绑定一个一次性的事件,该事情将会触发一次后自动失效

5.4 简单文件读取

/*
  fs.readFile(path[, options], callback)
  fs.readFileSync(path[, options])
     - path  要读取的文件路径
     - options  读取的选项
     - callback  回调函数
*/
// ---------- read.json -----------
{
  "data": [
    {
      "name": "lucy",
      "age": 18
    }, {
      "name": "Tim",
      "age": 22
    }
  ],
  "test": "i am test"
}
// ---------- read.js -----------
let fs = require('fs')
fs.readFile('./read.json', (err, data) => {
  if (!err) {
    let myData = JSON.parse(data.toString())
    let str = ''
    for (let i = 0; i < myData.data.length; i++) {
      str = str + '我的名字是' + myData.data[i].name + ', 我今年' + myData.data[i].age + '岁了!'
    }
    fs.writeFile('read.txt', str, (err) => {
      if (!err) {
        console.log('数据写入成功!')
      }
    })
  }
})
// ---------- read.txt -----------
我的名字是lucy, 我今年18岁了!我的名字是Tim, 我今年22岁了!

5.5 流式文件读取

let fs = require('fs')
// 创建一个可读流
let rs = fs.createReadStream('050704.png')
let ws = fs.createWriteStream('05070401.png')
let ws1 = fs.createWriteStream('05070402.png')
rs.once("open", () => {
  console.log('r-打开')
})
rs.once("close", () => {
  console.log('r-关闭')
  ws.end() // 数据读取完毕,关闭可写流
})
ws.once("open", () => {
  console.log('w-打开')
})
ws.once("close", () => {
  console.log('w-关闭')
})
// 方法1 如果要读取一个可读流中的数据,必须要为可读流绑定一个data事件,data事件绑定完毕,它会自动开始读取数据
rs.on("data", (data) => {
  console.log(data)
  ws.write(data)
})
// 方法2 可以直接将可读流的内容写到可写流中
// rs.pipe(ws1)

PS F:\node\fs> node streamRead.js
r-打开
w-打开
<Buffer 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 01 0d 00 00 01 21 08 06 00 00 00 65 7c f5 45 00 00 00 01 7
3 52 47 42 00 ae ce 1c e9 00 00 00 04 ... >
<Buffer 05 79 93 6b 00 00 f0 3b 49 44 41 54 a0 6e fa ce ac 56 5b db 32 7e 8b 2a f7 da 8d 57 b3 2e dc 37 92 7d 80 55 0d b
a 84 77 02 3a d5 7f fd 1b eb cb 03 30 ... >
r-关闭
w-关闭

5.6 其他操作

  • 验证路径是否存在:fs.existsSync(path)
  • 获取文件信息:fs.stat(path, callback)   fs.statSync(path)
  • 删除文件:fs.unlink(path, callback)  fs.unlinkSync(path)

 

 


下一篇。。。

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值