node.js的Buffer、fs模块

总结

node如何操作js文件

一、node如何操作js文件

  1. 借助于插件:Code Runner
  2. 在想要运行js文件的文件夹,右键,在终端中运行,注意终端的路径要和文件所在的路径一致[推荐]
  3. 在文件夹中的地址栏里面敲入cmd,在使用node命令运行某一个文件

内置模块

二、内置模块

Buffer
  1. Buffer
    类似于数组的一个对象
  1. 如何创建Buffer
    1.1 直接创建:let 变量 = Buffer.alloc(字节大小)
    1.2 通过字符串创建:let 变量 = Buffer.from("字符串");
    1.3 不安全方式创建:let 变量 = Buffer.allocUnsafe(字节大小)
  1. 转换[后期用的偏多]
    let 变量 = Buffer.from("字符串");
    变量.toString();
    或者 变量+'' 变量加空字符串的形式也可以将buffer值变为字符串
    或者 buffer + buffer 会隐式转化为字符串
  1. 读取和写入
    let 变量 = Buffer.alloc(字节大小)
    console.log(变量[下标])
    变量[下标] = 值;
fs[重点] 操作磁盘中的文件/文件夹

fs[重点] 操作磁盘中的文件/文件夹

文件
同步与异步的区别:先执行同步代码后执行异步代码

  • 文件写入

    • 异步写入 :fs.writeFile(写入路径,写入内容,[写入形式],回调函数) [后期用的偏多]
      路径可以是相对路径,也可以是绝对路径
      写入内容必须是字符串
      写入形式:{flag:‘a’} a:append追加 默认:{flag:‘w’} w:write写入
      回调函数:err=>{} err结果受写入路径影响,如果可以正常写入为null,否则为错误信息

    • 同步写入:fs.writeFileSync(写入路径,写入内容,[写入形式])

    • 流式写入:let ws = fs.createWriteStream(写入路径)
      ws.write("写入内容");
      ws.close();

  • 文件读取

    • 异步读取: fs.readFile(文件路径,回调函数) [后期用的偏多]
      路径可以是相对路径,也可以是绝对路径
      回调函数:(err,data)=>{}
      err结果受写入路径影响,如果可以正常写入为null,否则为错误信息
      data是文件内容,但是结果类型为Buffer,如果想要得到具体文件的内容需要转换成字符串,调用toString()

    • 同步读取: let 变量 = fs.readFileSync(文件路径)
      变量得到的结果类型为Buffer,如果想要得到具体文件的内容需要转换成字符串,调用toString()

    • 流式读取
      let 变量 = fs.createReadStream(文件路径);
      变量.on(‘data’,chunk=>{
      console.log(chunk.toString());
      })
      回调函数的参数可以自定义
      chunk参数得到的结果类型为Buffer,如果想要得到具体文件的内容需要转换成字符串,调用toString()
      简写形式
      rs.pipe(变量 ); 直接获取到读取的内容

  • 文件移动/重命名
    移动:fs.rename(文件的旧路径,文件的新路径,回调函数);
    重命名:fs.rename(文件的旧名称,文件的新名称,回调函数);
    回调函数:err=>{}
    err结果受写入路径影响,如果可以正常写入为null,否则为错误信息
    注:如果第二个参数为名称则是重命名,为路径则是移动,为路径和名称则是移动和重命名;移动的目录一定要是存在的

  • 文件删除
    fs.unlink(文件路径,回调函数)
    回调函数:err=>{}
    err结果受写入路径影响,如果可以正常写入为null,否则为错误信息

  • 文件夹

    • 创建:fs.mkdir(路径,{ recursive: true },回调函数)
      回调函数:err=>{}
      err结果受写入路径影响,如果可以正常写入为null,否则为错误信息

    • 读取: fs.readdir(路径,回调函数)
      回调函数:(err,data)=>{}
      err结果受写入路径影响,如果可以正常写入为null,否则为错误信息
      data是文件夹内容

    • 删除: fs.rm(路径,{ recursive: true },回调函数)
      回调函数:err=>{}
      err结果受写入路径影响,如果可以正常写入为null,否则为错误信息
      不管是创建还是删除,都可以是递归创建/递归删除:{ recursive: true }

  • 路径

    ./: 在node中表示运行终端时所在的路径
    ../:传统意义的上一级目录
    __dirname:文件定义时所在的绝对路径

  • 文件资源状态
    fs.stat(文件路径/文件夹路径,回调函数)

// Buffer 创建方式
let buffer1 = Buffer.alloc(10);
let buffer2 = Buffer.from("我喜欢瑶瑶");
let buffer3 = Buffer.allocUnsafe("我喜欢瑶瑶");

// Buffer的转换
let data = Buffer.from("我喜欢瑶瑶");//data是数组
data.toString();//方法一
console.log(data + '');//方法二

// Buffer的读取和写入
// data.[下标]  读取
data[2] = 300;//写入

const fs = require('fs');
// 文件的写入
//异步写入
fs.writeFile('./index.html','我要写入文件',{flag:'a'},err=>{//{flag:'w'}
  if(err) throw err;
  console.log('写入成功')
});
//同步写入
fs.writeFileSyn('./index.css','div{color:"red"}')
// 流式写入
let ws = fs.createWriteStream('./index.html');
ws.write('写入内容1');
ws.write('写入内容2');
ws.close();

// 文件读取
// 同步读取
fs.readFile('./index.html',(err,data)=>{
  if(err) throw err;
  console.log('读取成功')
  console.log(data.toString());
})
// 异步读取
let data = fs.readFileSync('./index.html');
console.log(data.toString());
//流式读取
let rs = fs.createReadStream('./index.html');
rs.on('data',chunk=>{
  console.log(chunk.toString());
})


// 文件的移动和重命名
fs.rename('./index.html','./index1.html',err=>{
  if(err) throw err;
  console.log('重命名成功')
})
fs.rename('./index.html','./index/index1.html',err=>{
  if(err) throw err;
  console.log('移动和重命名成功')
})
// 如果第二个参数为名称则是重命名,为路径则是移动,为路径和名称则是移动和重命名;移动的目录一定要是存在的`

// 文件的删除
fs.unlink('./index.html',err=>{
  if(err) throw err;
  console.log('删除成功')
})


// 文件夹的操作
// 创建
//如果想要一次性的创建文件夹嵌套,必须传递第二个参数为recursive: true
fs.mkdir('./css',err=>{
  if (err) throw err;
  console.log('创建目录成功')
})
fs.mkdir('./css/css1',{recursive:true},err=>{
  if (err) throw err;
  console.log('创建目录成功')
})
// 读取文件夹
fs.readdir('./css',(err,data)=>{
  if (err) throw err;
  console.log('读取文件夹成功');
  console.log(data);//[]数组形式的文件夹名
})
//删除文件夹
fs.rm('./demo',{recursive:true},err=>{
    if(err) throw err;
    console.log('删除文件夹成功');
})

一、介绍

Node.js® 是一个基于 Chrome V8 引擎JavaScript 运行时环境

官网:https://nodejs.org/zh-cn/

中文网站:http://nodejs.cn/

说明文档:http://nodejs.cn/api-v16/

作用:

  • 解析运行 JS 代码 【不能运行DOM,BOM】

  • 操作系统资源,如内存、硬盘、网络

应用场景:

  • APP 接口服务

  • 网页聊天室

  • 动态网站, 个人博客, 论坛, 商城等

  • 后端的Web服务,例如服务器端的请求(爬虫),代理请求(跨域)

  • 前端项目打包(webpack, gulp)

二、下载

下载地址:https://nodejs.org/zh-cn/download/

历史版本:https://npm.taobao.org/mirrors/node/

在这里插入图片描述

双击打开安装文件,一路下一步即可😎,默认的安装路径是 C:\Program Files\nodejs

或者可以命令行窗口中where node,回车,也能查看node的安装地址

在这里插入图片描述

安装完成后,在 CMD 命令行窗口下运行 node -v,如显示版本号则证明安装成功,反之安装失败,重新安装。

三、基本使用

3.1 交互模式

在命令行下输入命令 node,这时进入 nodejs 的交互模式
在这里插入图片描述

3.2 文件模式 【重要】

创建文件hello.js,并写入代码 console.log(‘hello world’),命令行运行 node hello.js

具体步骤:

  • 打开命令行工具(win+R)

  • 修改默认目录为实际文件所在目录

    • 切换盘符:『盘符名称:』
    • 切换目录:『cd 目录名称:』
    • 查看当前目录下文件列表:『dir』
  • 运行命令(node 文件名)

注意:js文件命名,不要写成node.js

快速启动命令行的方法

  • 在文件夹上方的路径中,直接输入 cmd 即可
    在这里插入图片描述
  • 使用 vscode 自带的命令行窗口

友情提示:vscode自带的命令行窗口如果无法操作node命令,可以按照以下步骤尝试:

1、先关闭vscode

2、在桌面的vscode右键=>兼容性=>管理员方式运行

3、重新打开vscode,终端键入node -v,如果有版本号,说明已经支持node命令了

4、在按照对应js文件所在路径,运行即可

在这里插入图片描述

也可以安装插件 『code Runner』, 文件右键 -> run code
在这里插入图片描述

注意:在 nodejs 环境下,不能使用 BOM 和 DOM ,也没有全局对象 window,全局对象的名字叫 global
在这里插入图片描述
document API只有在浏览器环境下才能使用。

练习1:横向输出数字1-10

练习2:输出以下图形

*
***
*****
*******
*********
    *
   ***
  *****
 *******
*********

练习3:九九乘法表

1*1=1	
1*2=2	2*2=4	
1*3=3	2*3=6	3*3=9	
1*4=4	2*4=8	3*4=12	4*4=16	
1*5=5	2*5=10	3*5=15	4*5=20	5*5=25	
1*6=6	2*6=12	3*6=18	4*6=24	5*6=30	6*6=36	
1*7=7	2*7=14	3*7=21	4*7=28	5*7=35	6*7=42	7*7=49	
1*8=8	2*8=16	3*8=24	4*8=32	5*8=40	6*8=48	7*8=56	8*8=64	
1*9=9	2*9=18	3*9=27	4*9=36	5*9=45	6*9=54	7*9=63	8*9=72	9*9=81

四、Buffer(缓冲器)【后期使用较少】

4.1 概念

Buffer是一个类似于数组的对象,不同的是Buffer是专门用来保存二进制数据的。

4.2 特点

  • Buffer在创建时,大小就被创建了,且是无法调整的
  • 性能较好:是直接对计算机的内存进行操作
  • 每个元素的大小为1字节(byte),相当于8个bit(也就是0和1)比特

4.3 使用

  • 创建Buffer

    • 直接创建:

      语法:let 变量名 = Buffer.alloc(数字)

      含义:

      创建了一个长度为数字字节的buffer,相当于申请了数字字节的内存空间,

      用来保存数据(文件、网络请求的数据)

      【注】这里的数字自定义大小

    • 不安全创建

      语法:let 变量名 = Buffer.allocUnsafe(数字)

    • 通过字符串创建

      语法:let 变量名 = Buffer.from(‘字符串内容’)

      含义:字符串中每一个字符都有对应的字节(十六进制数值)

  • Buffer读取和写入

    可以直接通过[]的方式对数据进行处理,可以使用toString()将Buffer输出为字符串。

    • []对buffer进行读取和设置
    let buf = Buffer.from('iloveyou');
    //写入
    buf[0] = 99;
    //读取
    console.log(buf[0]);
    console.log(buf);
    
    • toString()是将Buffer转化为字符串 【相对常用一些】
    console.log(buf.toString());
    

4.4 关于溢出

溢出的高位数据会舍弃

4.5 关于中文

一个 UTF-8 的中文字符大多数情况都是占3个字节

4.6 关于单位换算

1 Bit 对应的是1个二进制位(0和1)

8 Bit = 1 字节(Byte)

五、fs模块以及文件操作 【很重要】

fs 全称为 file system,称之为文件系统,是 NodeJS 中的内置模块,对计算机中的磁盘文件进行增删改查等操作。

5.1 文件写入

  • 简单写:writeFile()方法

执行步骤:

1、导入模块:

语法:const 变量名 = require(“fs”)

解释:

  • require()是一个node的内置函数(不需要程序员单独声明),用来导入node中对应的模块

  • fs属于模块名称,不能修改

2、调用对应方法,创建文件并写入相应内容

语法:变量名.writeFile(“文件路径”,“文件写入的内容”,[options],回调函数)

【注】回调函数的写法使用匿名函数或者箭头函数均可

3、该方法属于异步写入方法

解释:

  • 回调函数中有一个默认的参数,名称可以自定义,一般可以写成error/err

  • 当向磁盘目录中写入文件时,发生错误,参数表示一个错误对象,否则为null

  • 文件路径支持相对路径绝对路径两种

    • 相对路径

      注意:./相对路径是指当前js脚本文件所在的文件夹目录

 //1、导入模块
 const fs = require("fs");
 //2、向磁盘目录中写入文件
 fs.writeFile("./index.html","这是一个新写入的内容",(error)=>{
     if(error){
         console.log('写入文件失败');
         console.log(error);
         return;
     }
     console.log('写入文件成功');

 })  
  • 绝对路径

    注意:绝对路径中所有位置文件夹必须存在,且路径的斜杠必须是"/",否则需要按照转义字符来转义

 //1、导入模块
 const fs = require("fs");
 //2、向磁盘目录中写入文件
 fs.writeFile("d:/index.html","这是一个新写入的内容",(error)=>{
     //如果写入没有发生错误
     if(error){
         console.log('写入文件失败');
         console.log(error);
         return;
     }
     console.log('写入文件成功');

 })  

案例1:

在D盘中创建一个文件(520快乐.md) 并写入内容"真诚永远都是必杀技"

//1.导入fs模块
const fs = require('fs');

//2.利用writeFile方法向文件写入内容

fs.writeFile('d:/520快乐.md','真诚永远都是必杀技',err=>{
    //throw 关键字用来抛出错误,后续代码将不会再执行,相当于return的功效
    if(err) throw err;
    console.log('写入成功');
});

案例2:要求将对象写入到文件中

//1.导入fs模块
const fs = require('fs');

//2.利用writeFile方法向文件写入内容

let data = {
	"id":4860,
	"uuid":"5e398eef-f5cf-4ff6-a000-c24913de86dd",
	"ditokoto":"世上之所以有不公平之事是由于当事人能力不足所致。",
	"type":"a",
	"from":"金木研",
	"from_who":null,
	"creator":"夕之树",
	"creator_uid":4248,
	"reviewer":4756,
	"commit_from":"web",
	"created_at":"1573331301",
	"length":22
}

let str = JSON.stringify(data);

fs.writeFile('index.json',str,err=>{
    //throw 关键字用来抛出错误,后续代码将不会再执行,相当于return的功效
    if(err) throw err;
    console.log('写入成功');
});

options参数:需要传入一个对象,键名为flag,键值根据需要设定

  • w(write):默认值 覆盖写
  • a(append):追加
//1、导入模块
const fs = require("fs");
//2、向磁盘目录中写入文件
fs.writeFile("./index.html","这是一个新写入的内容",{flag:'a'},(error)=>{
    //如果写入没有发生错误
    if(error){
        console.log('写入文件失败');
        console.log(error);
    }else{
        console.log('写入文件成功');
    }
})  
  • writeFileSync()方法

注:该方法属于同步写入方法

1、导入模块:

语法:const 变量名 = require(“fs”)

2、调用对应方法,创建文件并写入相应内容

语法:变量名.writeFileSync(“文件路径”,“文件写入的内容”,[options])

注意:该方法没有回调函数

//1、导入模块
const fs = require("fs");
//2、向磁盘目录中写入文件
fs.writeFileSync("./index.css","*{margin:0;padding:0}")

区别同步和异步:如果代码的编写顺序和执行顺序一致:同步执行;否则就是异步执行;

关于线程执行效率
同步会阻塞较慢
异步不会阻塞较快
//1、导入fs模块
const fs = require('fs');

//2、向目录中写入文件
fs.writeFile('./index.html', "这是一个新写入的内容", error => {
    //如果写入有错误就抛出错误
    if (error) throw error;
    console.log('追加内容成功');
    console.log('执行1');
})
console.log('执行2');

一般自己练习写案例时,可以使用writeFileSync()同步方法;

但如果写服务或者给其他人提供服务,就必须选择writeFile()异步方法。

  • 流式写入 【使用较少】

执行步骤:

1、导入模块:

语法:const 变量名 = require(“fs”)

解释:

  • require()是一个node的内置函数(不需要程序员单独声明),用来导入node中对应的模块

  • fs属于固定名称,不能修改

2、调用对应方法,创建文件并写入相应内容

语法:变量名.createWriteStream(“文件路径”)

​ 返回一个写入流对象,调用write方法完成内容的写入

//1、导入模块
const fs = require("fs");
//2、创建写入流对象
const ws = fs.createWriteStream("./data.txt")  

//3、写入内容
ws.write("今夕明夕");
ws.write("学之习之");

//4、关闭写入流
ws.close();

总结:

1、writeFile:主要针对于写入次数较少的情况,例如:1次,2次等

2、createWriteStream:针对于次数比较多的情况

  • 写入文件的场景(当需要持久化的保存数据的时候,要想到【文件写入】)
    • 下载文件
    • 安装软件
    • 日志(程序日记)如Git
    • 数据库
    • 网盘
    • 编辑器保存文件
    • 视频录制

5.2 文件读取

  • 简单读取
    • readFile()方法

执行步骤:

1、导入模块:

语法:const 变量名 = require(“fs”)

解释:

  • require()是一个node的内置函数(不需要程序员单独声明),用来导入node中对应的模块

  • fs属于固定名称,不能修改

2、调用对应方法,读取相应内容

语法:变量名.readFile(“文件路径”,回调函数)

【注】回调函数的写法使用匿名函数或者箭头函数均可,读取的内容默认为Buffer,可以借助toString()

//1.导入fs模块
const fs = require('fs');

//2.利用readFile来读取文件
fs.readFile('./aa.txt',(err,data)=>{
    if(err) throw err;
    //查看文件内容
    console.log(data.toString());
});
  • readFileSyns()方法

1、导入模块:

语法:const 变量名 = require(“fs”)

2、调用对应方法,创建文件并写入相应内容

语法:变量名.readFileSyns(“文件路径”)

//1.导入fs模块
const fs = require('fs');

//2.利用readFile来读取文件
const data = fs.readFileSync('./aa.txt');
console.log(data.toString());

5.3 流式读取

执行步骤:

1、导入模块:

语法:const fs = require(“fs”)

解释:

  • require()是一个node的内置函数(不需要程序员单独声明),用来导入node中对应的模块

  • fs属于固定名称,不能修改

2、调用对应方法,创建读取流对象,读取相应内容

语法:const rs = fs.createReadStream(“文件路径”)

3、绑定事件

调用流对象中的on方法,其中事件名为data,固定语法

语法:rs.on(‘data’,chunk=>{})

//1、引入fs模块
const fs = require('fs');
//2、创建流对象
const ws = fs.createReadStream('.index.json');
//3、绑定事件
ws.on('data', chunk => {
    //4、获取到的数据是buffer
    console.log(chunk.toString());
});

那么,既然readFile和createReadStream都可以读取文件,那么如何选择呢?

readFile更适合于小文件的读取;

createReadStream更适合于大文件的读取;

//1、引入模块
const fs = require('fs');
//2、获取读取文件流
const rs = fs.createReadStream('./3.txt');
//4、获取写入流对象
const ws = fs.createWriteStream('./5.txt');
//3、通过这个对象中的on方法,绑定一个事件,用于读取文件的内容
//相对比与间歇性时,这种格式还可以在原文件读取的内容基础之上新增新的内容,一起写入到新的文件
//这种格式相对更灵活
rs.on('data', chunk => {
    //chunk这个参数名可以自定义,得到的结果是Buffer
    ws.write(chunk.toString() + '新的内容');
});

//5、简写形式
// rs.pipe(ws);

案例1:读取文件

C:\Windows\Boot\BootDebuggerFiles.ini

//1、引入fs模块
const fs = require('fs');
//2、读取文件
fs.readFile("C:\\Windows\\Boot\\BootDebuggerFiles.ini", (err, data) => {
    if (err) throw err;
    console.log(data.toString());
})

案例2:复制文件

//1、引入fs模块
const fs = require('fs');
//2、创建对象
const rs = fs.createReadStream('./data.txt');
const ws = fs.createWriteStream('./data1.txt');
//3、读取数据
/* rs.on('data', chunk => {
    ws.write(chunk);
}) */

//简写形式,相当于中间有一个管道,文件读取一点就写入一点
rs.pipe(ws);

文件读取的应用场景:

  • 下载文件
  • 程序运行
  • 数据读取(数据库)
  • 日志
  • 编辑器打开文件

5.4 文件移动与重命名

文件移动:fs.rename(文件旧路径,文件新路径,回调函数);

文件重命名:fs.rename(文件旧路径,文件新的名称,回调函数)

注:如果第二个参数为名称则是重命名,为路径则是移动,为路径和名称则是移动和重命名;移动的目录一定要是存在的

//1.导入fs模块
const fs = require('fs');

//2.使用rename方法来完成重命名以及移动
fs.rename('bb.txt','./demo/cc.html',err=>{
    if(err) throw err;
    console.log('执行成功');
});

5.5 文件的删除

//1.导入fs模块
const fs = require('fs');

//2.利用unlink方法来删除文件
fs.unlink('./demo/cc.html',err=>{
    if(err) throw err;
    console.log('执行成功');
});

5.6 文件夹的操作

创建:fs.mkdir(创建的路径,{recursive:true},回调函数)

读取:fs.readdir(路径,回调函数)

删除:fs.rm(路径,回调函数)

​ 文件夹删除的时候如果不是空文件夹,不能删除;

​ 想要删除空文件夹则需要添加一个选项:fs.rm(路径,{recursive:true},回调函数)

//1.导入fs模块
const fs = require('fs');
//2.创建文件夹
/* fs.mkdir('./newdir',err=>{
    if(err) throw err;
    console.log('创建文件夹成功');
}); */

//递归创建文件夹
/* fs.mkdir('./newdir/a1/b1/c1',{recursive:true},err=>{
    if(err) throw err;
    console.log('创建文件夹成功');
}); */

//3.读取文件夹
/* fs.readdir('./demo',(err,file)=>{
    if(err) throw err;
    console.log('文件路径',file);
}) */

//4.删除文件夹
fs.rm('./demo',{recursive:true},err=>{
    if(err) throw err;
    console.log('执行成功');
})

5.7 文件路径问题

  • ./: 当前文件所在的文件夹(通用型的解释 :在node中表示运行终端时所在的路径)
  • ./: 在nodejs fs模块的方法中,表示的是运行命令时,命令行所在的工作目录
  • __dirname:表示当前文件所在文件夹的绝对路径
//1.导入fs模块
const fs = require('fs');
fs.writeFile(__dirname + '/index.html',err=>{
    if(err) throw err;
    console.log('写入成功');
});

以后使用fs模块进行文件相关操作的时候,都可以使用__dirname将相对路径转化为绝对路径,最终让代码运行,

不受运行命令位置的影响。

5.8 查看目标资源状态

语法:fs.stat(文件路径,(err,stats)=>{})

作用:查看目标资源的状态,例如:文件大小、创建时间、文件类型等

//1.导入fs模块
const fs = require('fs');
//2.调用stat方法
fs.stat(__dirname + '/index.html',(err,stats)=>{
    //err:错误对象
    console.log(err);
    //stats:状态对象
    console.log(stats);
    //获取文件最后一次访问的时间;
    console.log(stats.atime.toLocaleString());
	//文件创建的时间;
    console.log(stats.birthtime.toLocaleString());
	//文件最后一次修改时间;
    console.log(stats.mtime.toLocaleString());
	//状态发生变化的时间;
    console.log(stats.ctime.toLocaleString())
    //检测目标资源是否为文件夹
    console.log(stats.isDirectory());
    //检测目标资源是否为文件
    console.log(stats.isFile());
})
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值