node基础与fs模块学习笔记

了解Node.js与内置模块

什么是Node.js?

Node.js® is an open-source, cross-platform JavaScript runtime environment.

node.js是一个开源跨平台的js运行环境

前端的运行环境就是浏览器。

注意:Node.js中无法调用DOM和BOM等浏览器内置API。

Node.js中的顶级对象为global,也可以用globalThis访问顶级对象.
如下代码会报错

// BOM
console.log(window);
console.log(history)
console.log(navigator)
console.log(location)

// DOM
console.log(document)
//AJAX
let xhr = new XMLHttpRequest();

浏览器中的JavaScript的组成部分

js核心语法:变量、数据类型;循环、分支、判断;函数、作用域、this等等

WebAPI:DOM操作、BOM操作,基于XMLHttpRequest的Ajax操作

为什么js可以在浏览器中执行

不同的浏览器有不同的JavaScript解析引擎:

Chrome浏览器的V8解析引擎性能最好。

node基础与fs模块学习笔记_第1张图片

为什么js可以操作DOM和BOM

每个浏览器都内置了DOM和BOM的API函数,因此浏览器中的js才可以调用他们。

浏览器中的JavaScript运行环境

运行环境是指代码正常运行所需要的必要环境。
V8引擎负责解析和执行JavaScript代码
内置API是由运行环境提供的特殊接口,只能在所属的运行环境中被调用。

JavaScript能否做后端开发

JavaScript借助node.js可以进行后台开发,单独不行。node.js可以作为后端运行环境和JavaScript完成后端开发。

node的安装和使用

node的安装

node官网可以下载两个版本,LTS是长期支持稳定版本,适用于企业大型项目。

current是最新的,可以尝试新特性但是可能存在漏洞和安全性问题。

终端输入node -v可以查看安装的版本

node的使用

  1. 打开终端win+r输入cmd进入终端
  2. 输入js文件的路径,cd可以切换路径 d:可以切换c盘d盘
  3. 运行命令:node demo.js

如何打开当前路径下的终端,可以在当前路径的地址栏输入cmd回车或者在空白处按住shift不松手鼠标右键打开powershell。

终端快捷键
↑ 快速定位到上次执行的命令
tab 快速补全路径
esc 快速清空当前输入的命令
cls 清空终端

文件写入

fs模块可以实现与硬盘的交互,例如文件的创建、删除、重命名、移动,还有文件内容的写入、读取,以及文件夹的相关操作。


若在js代码中使用fs模块操作文件,需要先导入

const fs=require(‘fs’)

writeFile异步写入

向指定文件中写入内容fs.writeFile(file, data[, options], callback)


file:必选参数,需要指定一个文件路径的字符串,表示文件的存放路径

data:必选参数,表示要写入的内容

options:可选参数,表示以什么编码格式来写入文件内容,默认值是utf8。

callback:必选参数,文件写入完成后的回调函数。

const fs = require('fs')
    fs.writeFile('./files/2.txt', 'hellonodejs', function (err) {
        
        console.log('写入成功!' + err)
        // 文件写入成功,err的值等于null
        // 文件写入失败,err的值等于一个错误对象
    })

运行结果截图
node基础与fs模块学习笔记_第2张图片

判断文件是否写入成功

const fs = require('fs')
    fs.writeFile('./files/2.txt', 'hellonodejs', function (err) {
        if (err) {
           return console.log('文件写入失败!'+err.message)
       }
        console.log('写入成功!' )
       
    })

运行截图
node基础与fs模块学习笔记_第3张图片
node基础与fs模块学习笔记_第4张图片

writeFileSync同步写入

fs.writeFileSync('./data.txt','test');

性能不高的场景可以使用同步写入。

appendFile/appendFileSync追加写入

fs.appendFile('./files/2.txt', '这是中文附加的字', err => {
    if (err) {
        console.log('写入失败');
        return;
    }
    console.log('追加写入成功')
});

fs.appendFileSync('./files/2.txt', '\r\n这是中文附加的字')

node基础与fs模块学习笔记_第5张图片

createWriteStream流式写入

语法: fs.createWriteStream(path[,options])

参数说明:

path文件路径

options选项配置(可选)


返回值:Object

代码示例:

// 1.导入fs模块
const fs = require('fs');
// 2.创建写入流对象
const ws = fs.createWriteStream('./files/给翠花的信.txt');
// 3.write
ws.write('亲爱滴翠花\r\n');
ws.write('我喜欢你很久了\r\n');
ws.write('可以借五毛钱嘛\r\n');
// 4.关闭通道
ws.close();

node基础与fs模块学习笔记_第6张图片

程序打开一个文件是需要消耗资源的,流式写入可以减少打开关闭文件的次数。

流式写入适用于大文件写入或者频繁写入的场景,writeFile适合与写入频率较低的场景。

写入文件的场景

当需要持久化保存数据的时候,应该想到文件写入

下载文件

安装软件

保存程序日志,如git

编辑器保存文件

视频录制

文件读取

readFile异步读取

fs.readFile(path[, options], callback)
path:必选参数,字符串,表示文件的路径。
options:可选参数,表示以什么编码格式来读取文件。
callback:必选参数,文件读取完成后,通过回调函数拿到读取的结果。

    const fs = require('fs')
    fs.readFile('./files/demo.txt', 'utf8', function (err, dataStr) {
        console.log(err)
        console.log('------')
        console.log(dataStr)
    })

callback回调函数,拿到读取的失败和成功的结果,err,dataStr

通过本路径下的powershell运行node

node 1

脚本文件名称过长使用tab键自动补全。

运行截图
node基础与fs模块学习笔记_第7张图片

读取成功err的值是null

读取失败err的值是错误对象,dataStr的值是undefined

判断文件是否读取成功

可以判断err对象是否是null,从而知晓文件读取的结果

    const fs = require('fs')
    fs.readFile('./files/demo.txt', 'utf8', function (err, result) {
        if (err) {
            return console.log('文件读取失败!' + err.message)
        }
        console.log('文件读取成功!' + result)
    })

运行结果截图
node基础与fs模块学习笔记_第8张图片

readFileSync同步读取

const fs = require('fs');

fs.readFile('./files/给翠花的信.txt', (err, data) => {
    if (err) {
        console.log('读取失败');
        return;
    }
    console.log(data.toString());
});

运行结果截图
node基础与fs模块学习笔记_第9张图片

createReadStream流式读取

const fs = require('fs');
const rs = fs.createReadStream('./files/匆匆那年.mp3');
rs.on('data', chunk => {
    console.log(chunk.length);
    console.log(chunk.toString());
})

流式读取chunk.length=65536字节对应的是64kb,就是流式读取每次在存储中读取64kb的内容。如果打印chunk.toString()会出现乱码,因为mp3音频不能打印成字符。
node基础与fs模块学习笔记_第10张图片

// end可选事件
rs.on('end',()=> {
    console.log('读取完成');
});

读取文件应用场景

  • 电脑开机
  • 程序运行
  • 编辑器打开文件
  • 查看图片
  • 播放视频
  • 播放音乐
  • git查看日志
  • 上传文件
  • 查看聊天记录

文件复制

第一种方式可以采用readFile读取文件内容,具体步骤先使用readFileSync读取文件,再用writeFileSync写入文件副本,即可完成。

const fs = require(('fs'));

let data = fs.readFileSync('./files/匆匆那年.mp3');

fs.writeFileSync('./files/匆匆那年-1.mp3', data);

第二种方法就是流式操作,创建读取流对象然后创建写入流对象,绑定data事件。

const fs = require(('fs'));
const rs = fs.createReadStream('./files/匆匆那年.mp3');
const ws = fs.createWriteStream('./files/匆匆那年-2.mp3');

rs.on('data', chunk => {
    ws.write(chunk);
});

运行结果截图
node基础与fs模块学习笔记_第11张图片

第二种方式占用资源更少一些,所以第二种方式更好一些。流式读取是块读取,内容一块一块被读取,占用的内存较少。
可以通过引入process模块,调用memoryUsage()方法查看内存占用情况。rss:表示node进程占用的内存总量。

const fs = require(('fs'));
const process = require('process');
let data = fs.readFileSync('./files/匆匆那年.mp3');

fs.writeFileSync('./files/匆匆那年-1.mp3', data);
console.log(process.memoryUsage());//rss
const rs = fs.createReadStream('./files/匆匆那年.mp3');
const ws = fs.createWriteStream('./files/匆匆那年-2.mp3');
//绑定data事件
rs.on('data', chunk => {
    ws.write(chunk);
});
rs.on('end', () => {                     
    console.log(process.memoryUsage());//24383488
})

node基础与fs模块学习笔记_第12张图片

在如图所示的rss值当中,流式操作的值更大因为文件太小。文件比较大的时候才会明显显示出流式操作更节约内存.
或者可以不绑定data事件,使用管道命令快速实现复制

rs.pipe(ws)

文件移动与重命名

在node.js中我们可以使用rename或者renameSync来移动和重命名文件或者文件夹

语法

fs.rename(oldPath,newPath,callback)

fs.renameSync(oldPath,newPath)

参数说明:

oldPath文件当前路径

newPath文件新的路径

callback操作后的回调

代码示例

const fs = require('fs')
fs.rename('./6文件赋值.js', './files/6文件复制.js', (err) => {
    if (err) throw err;
    console.log('移动完成')
});
fs.renameSync('./6文件赋值.js', './files/6文件复制.js');

node基础与fs模块学习笔记_第13张图片

文件删除

Node.js中使用unlink或者unlinkSync来删除文件

语法

fs.unlink(path,callback)

fs.unlinkSync(path)

参数说明:

path文件路径

callback操作后的回调

代码示例

const fs = require('fs')

fs.unlink('./test.txt', err => {
    if (err) throw err;
    console.log('删除成功');
});
fs.unlinkSync('./test2.txt');

node基础与fs模块学习笔记_第14张图片
node基础与fs模块学习笔记_第15张图片

// 调用rm方法     rmRync
fs.rm('./论语.txt', err => {
    if (err) {
        console.log('delete successfully');
        return;
    }
    console.log('删除成功');
})

node基础与fs模块学习笔记_第16张图片

文件夹操作

借助Node.js的能力,我们可以对文件夹进行创建、读取、删除等操作

mkdir/mkdirSync 创建文件夹

readdir/readdirSync 读取文件夹

rmdir/rmdirSync 删除文件夹

mkdir创建文件夹

fs.mkdir(path[,options],callback)

fs.mkdirSync(path[,options])

options选项配置(可选)

下面的代码可以创建一个名称为html的文件夹

const fs = require('fs');
fs.mkdir('./html', err => {
    if (err) {
        console.log('创建失败');
        return;
    }
    console.log('创建成功');
});

下面看一下递归创建文件夹的代码

fs.mkdir('./a/b/c', { recursive: true }, err => {
    if (err) {
        console.log('创建失败');
        return;
    }
    console.log('创建成功');
});

注意递归创建需要{ recursive: true },才可以成功的创建。

readdir读取文件夹

那么如何读取文件夹呢

fs.readdir('./files', (err, data) => {
    if (err) {
        return console.log('读取失败');
    }
    console.log(data);
});

node基础与fs模块学习笔记_第17张图片

rmdir删除文件夹

rm;remove移除
下面的代码用来演示删除html文件夹

const fs = require('fs');
fs.rmdir('./html', err => {
    if (err) {
        return console.log('删除失败')
    }
    console.log('删除成功');
});
// 递归删除
fs.rmdir('./a', { recursive: true }, err => {
    if (err) {
        return console.log('删除失败');
    }
    console.log('删除成功');
});

node基础与fs模块学习笔记_第18张图片

查看资源状态

stat或者statSync查看资源的详细信息

代码示例

const fs = require('fs');
fs.stat('./files/匆匆那年.mp3', (err, data) => {
    if (err) {
        return console.log('操作失败')
    }
    console.log(data);
    console.log(data.isFile());
    console.log(data.isDirectory());
});

结果值对象结构:size文件体积,birthday创建时间,mtime最后修改时间
isFile检测是否为文件,isDirectory检测是否是文件夹

相对路径和绝对路径

const fs = require('fs');

// 相对路径
fs.writeFileSync('./index.html', 'love');
fs.writeFileSync('index.html', 'love');
fs.writeFileSync('../index.html', 'love');

// 绝对路径
fs.writeFileSync('D:/index.html', 'love');
fs.writeFileSync('/index.html', 'love');

相对路径参照物:命令行的参照物

相对路径问题

在使用fs模块操作文件时。如果提供的操作路径是以./或者…/开头的相对路径时,很容易出现路径动态拼接错误的问题。
原因:代码在运行的时候,会以执行node命令所处的目录,动态拼接出被操作文件的完整路径。
node基础与fs模块学习笔记_第19张图片

fs.readFile('./files/1.txt','utf8',function(err.,dataStr){
    if(err){
        return console.log('读取文件失败!'+err.message)
    }
    console.log('读取文件成功!'+dataStr)
})

如果出现了路径拼接错误的问题,是因为提供了./或者…/开头的相对路径

如果要解决这个问题,可以直接提供一个完整的文件存放路径就行

fs.readFile('D:\\VUE\\nodejs\\files\\1.txt','utf8',function(err,dataStr){
    if(err){
        return console.log('读取文件失败!'+err.message)
    }
    console.log('读取文件成功!'+dataStr)
})

_dirname

// __dirname表示当前文件所处目录的绝对路径
console.log(__dirname)

__dirname所代表的值不会随着执行命令node路径动态拼接而变化,是个恒定的值
node基础与fs模块学习笔记_第20张图片

最佳实践

fs.readFile(__dirname+'./files/1.txt','utf8',function(err,dataStr){
    if(err){
        return console.log('读取文件失败!'+err.message)
    }
    console.log('读取文件成功!'+dataStr)
})

练习-考试成绩整理

使用fs文件系统模块,将素材目录下成绩.txt文件中的考试数据,整理到成绩-ok.txt文件中

核心实现步骤

  1. 导入需要的fs文件系统模块
  2. 使用fs.readFile()方法,读取素材目录下的成绩.txt文件
  3. 判断文件是否读取失败
  4. 文件读取成功后,处理成绩数据
  5. 将处理完成的成绩数据,调用fs.writeFile()方法,写入新文件成绩-ok.txt中
// 1.导入fs模块
const fs = require('fs')

// 2.调用fs.readFile()读取文件内容
fs.readFile('./素材/成绩.txt', 'utf8', function (err, dataStr) {
// 3.判断是否读取成功
    if (err) {
        return console.log('读取文件失败!'+err.message)
    }

    // console.log('读取文件成功'+dataStr)
// 4.1先把成绩的数据,按照空格进行分割
    const arrOld = dataStr.split(' ')
    
// 4.2循环分割后的数组,对每一项数据进行字符串的替换操作
    const arrNew = []
    arrOld.forEach(items => {
        arrNew.push(items.replace('=',':'))
    })
// 4.3把新数组中的每一项,进行合并,得到一个新的字符串
    const newStr = arrNew.join('\r\n')
    console.log(newStr)
       
    fs.writeFile('./files/成绩-ok.txt', newStr, function (err) {
    if (err) {
        return console.log('成绩写入失败'+err.message)
    }
    console.log('成绩写入成功')
    })
})

node基础与fs模块学习笔记_第21张图片
node基础与fs模块学习笔记_第22张图片
node基础与fs模块学习笔记_第23张图片

练习

批量重命名

首先,输出files文件夹的所有文件信息

const fs = require('fs');
// 读取code文件夹
const files = fs.readdirSync('./files');
// 遍历数组
files.forEach(item => {
    console.log(item);
})

终端输出:

PS D:\VUE\nodejs> node .\14批量重命名.js
1.txt
2.txt
3.txt
6文件复制.js
demo.txt
匆匆那年-1.mp3
匆匆那年-2.mp3
匆匆那年.mp3
成绩-ok.txt
给翠花的信.txt
完整的代码

const fs = require('fs');
// 读取code文件夹
const files = fs.readdirSync('./files');
// 遍历数组
files.forEach(item => {
// 拆分文件名
    let data = item.split('-');
    let [num, name] = data;
    // 判断
    if (Number(num) < 30) {
        num = '0' + num;
    }
    // 创建新的文件名
    let newName = num + '-' + name;
    // console.log(newName);
    // 重命名
    fs.renameSync(`./files/${item}`, `./files/${newName}`);
})

总结注意点

fs提供了同步、回调和基于promise的三种形式。同步api会阻塞线程,但对于某些场景,使用同步方法会更方便、更易理解

尽量使用promise方式,回调容易造成嵌套地狱

对于大文件,使用文件流的方式来读写文件 createReadStream 和 createWriteStream 来减少内存占用

三方npm包 fs-extra 是fs的一个拓展,提供了很多更方便的api

.forEach(item => {
// 拆分文件名
    let data = item.split('-');
    let [num, name] = data;
    // 判断
    if (Number(num) < 30) {
        num = '0' + num;
    }
    // 创建新的文件名
    let newName = num + '-' + name;
    // console.log(newName);
    // 重命名
    fs.renameSync(`./files/${item}`, `./files/${newName}`);
})

总结注意点

fs提供了同步、回调和基于promise的三种形式。同步api会阻塞线程,但对于某些场景,使用同步方法会更方便、更易理解

尽量使用promise方式,回调容易造成嵌套地狱

对于大文件,使用文件流的方式来读写文件 createReadStream 和 createWriteStream 来减少内存占用

三方npm包 fs-extra 是fs的一个拓展,提供了很多更方便的api

你可能感兴趣的:(前端,node.js)