3.2-fs和path模块
Create by fall on 04 Nov 2020 Recently revised in 13 Mar 2024
fs 模块
对于文件或者文件夹的操作通过 fs
模块进行操作,对于文件路径的操作通过 path
模块实现。
文件夹操作
创建文件夹的完整示例
const fs = require('fs')
// fs.makedir(path[,mode],callback)
// mode 为目录的权限,默认是 777
fs.mkdir('./active', (err) => {
if (err) {
console.log(err);
return
} else {
console.log('文件夹创建成功'); // 就这几行代码就可以实现,对于文件夹的创建。
}
})
修改文件夹名称
const fs = require('fs')
var dirName = './active'
fs.rename(dirName,'./别介啊',(err)=>{
if (err) {
console.log(err);
return
} else {
console.log('名称修改完成');
}
})
删除文件夹
fs.rmdir('./别介啊',(err)=>{
if(err){
console.log("移除出现问题");
console.log(err);
}else{
console.log("移出成功");
}
})
因为必须删除文件夹内的所有文件,才能删除文件夹,此时如果想要一次性删除文件夹和里面的内容,需要依次删除文件,然后删除文件夹。也可以使用库直接实现,参看最删除文件夹。
文件的操作
文件系统的标志
a
打开文件进行追加。如果文件不存在则创建文件。a+
打开文件用于读取和追加。如果文件不存在则创建文件。as
同步模式追加文件,as+
同步模式,读取 或者追加文件r
打开文件用于读取,如果不存在,会产生异常r+
打开文件用于读写,如果不存在,会产生异常。rs+
以同步的方式打开文件进行读写,指示操作系统绕过本地文件系统缓存。w
打开文件进行写入,创建(不存在时)或是截断(存在该文件)w+
打开文件用于读写,如果文件不存在则创建文件。
a
、a+
、w
、w+
、添加 x
后,如果路径存在则失败,其他都相同
const fs = requrie('fs')
// fs.open(path,flags[,mode],callback)
fs.open('./package.json','a','777',()=>{
// 回调函数
})
写入文件
主要使用格式 fs.writeFile(file, data[, options], callback)
// 写入文件
var fs = require('fs');
fs.writeFile('./hello.txt',msg,'utf8',function(err){
if(err){
console.log('写入文件出错:'+ err);
}else{
console.log('writen successful');
}
})
fs.writeFile('/Users/joe/test.txt', content, { flag: 'a+' }, err => {})
追加文件可以直接通过
fs.appendFile('fileName',content,'utf-8',err=>{})
读取文件
书写格式:fs.readFile(path[, options], callback)
var fs = require('fs');
// 读取文件
fs.readFile('./hello.txt','utf8',function(err,data){
if(err){
throw err;
}
console.log(data);
})
剪切文件
剪切文件的方式,其实就是重命名文件名称
fs.rename('file.js', 'node_modules/file.js', (err) => {
if(err) {
console.log(err);
return false;
} else {
console.log("剪切成功!");
}
})
关闭文件
常用的方法
文件的常用方法
fd
为通过 fs.open()
方法返回的文件描述符
方法名称 | 方法功能 |
---|---|
fs.open() | 打开文件 |
fs.writeFile() | 写入文件 |
fs.read() | 参数分别为(fd, buffer, offset, length, position, callback) |
fs.appendFile() | 对文件进行数据追加,如果没有文件,创建并写入 |
fs.chmod() | 更改文件权限 |
fs.lchmod() | |
fs.close() | 关闭文件 |
fs.unlink() | 删除文件,参数 path,callback |
fs.ftruncate() | 截取文件 fd,len,callback |
文件夹的常用方法
mode
表示权限path
表示路径
方法名称 | 方法功能 |
---|---|
fs.mkdir() | 创建目录,参数(path[,mode],callback ) |
fs.readdir() | 读取目录,参数(path,callback ) |
fs.rmdir() | 删除目录,参数(path,callback ) |
文件的操作中,围绕着文件的权限。
如果有读,写,执行,这三个权限,二进制中这些权限就表示为 111。十进制中表示为 7。
当然不同身份的用户可以进行权限设置:自己,组内用户,一般用户的权限可以分别进行设置,777,表示三个用户都有读,写,执行的权限。
IO 机制
你要拷贝一个 20G 大的文件,如果你一次性将 20G 的数据读入到内存,你的内存条可能不够用, 或者严重影响性能. 但是你如果使用一个 1MB 大小的缓存 (buf) 每次读取 1Mb, 然后写入 1Mb, 那么不论这个文件多大都只会占用 1Mb 的内存。
而在 Node.js 中, 原理与上述 C 代码类似,不过在读写的实现上通过 libuv 与 EventEmitter 加上了异步的特性。在 linux/unix 中你可以通过 |
来感受到流式操作
JavaScript 语言自身只有字符串数据类型,没有二进制数据类型。
但在处理像TCP流或文件流时,必须使用到二进制数据。因此在 Node.js中,定义了一个 Buffer
类,该类用来创建一个专门存放二进制数据的缓存区。
在 Node.js 中,Buffer
类是随 Node 内核一起发布的核心库。Buffer
库为 Node.js 带来了一种存储原始数据的方法,可以让 Node.js 处理二进制数据,每当需要在 Node.js 中处理I/O操作中移动的数据时,就有可能使用 Buffer
库。原始数据存储在 Buffer
类的实例中。一个 Buffer
类似于一个整数数组,但它对应于 V8 堆内存之外的一块原始内存。
path
相对于当前执行文件时的路径,而不是该文件的目标路径
解决方法
-
__dirname
当前.js
文件所在的目录 -
__filename
__dirname
+ 当前文件名
这两个变量并不是全局使用的,只不过是执行文件时有个沙箱,沙箱提供了该功能
由于 linux
、windows
、MacOS
使用不同的路径解析方式,因此会使用 path 中的 join 进行拼接。
const path = require('path')
path.join(__dirname,'hello.txt')
文件操作时,无需判断文件是否存在,直接进行操作,如果不存在会反映在 error 对象中
module
如果使用了 ES6 的语法,需要一些特殊方法去获取当前目录和拼接
import { resolve as pathResolve } from 'path'
import { fileURLToPath } from 'node:url'
const __dirname = fileURLToPath(new URL('.', import.meta.url))
pathResolve(__dirname, 'hello.txt')
其它操作
删除文件夹
插件安装npm i fs-extra
const fs = require('fs-extra')
const folder = '/Users/joe'
fs.remove(folder, err => {
console.error(err)
})
同步执行代码
const fs = require('fs')
// 第一种方法:将 fs.readFile 同步化
const {promisify} = require('util')
const readFile = promisify(fs.readFile)
readFile('./package.json','utf-8').then(res=>{
console.log(res);
})
// 第二种方法:直接使用同步方法
const {promises} = require('fs')
promises.readFile('./package.json','utf-8').then(data=>{
console.log(data)
})
// 第三种方法:使用同步后的方法,进行 generator
const {promisify} = require('util')
const readFile = promisify(fs.readFile)
function* read(){
yield readFile('./package.json')
}
let generate = read()
generate.next().value.then(data=>{
console.log(data);
})
// 第四种方法
const {promisify} = require('util')
// const readFile = promisify(fs.readFile)
async function outFile(){
let a = await fs.readFileSync('./package.json')
console.log(a)
}
outFile()
文件流
管道流,链式流
管道流就像是把一个文件和另一个文件连接起来,传送数据
链式流,就像是一个文件,先做操作一,在做操作二,再做操作三
流,就像是文件的操作,把文件慢慢的从一个点,流向另一个点,从而实现复制(一般用于大文件的复制)。
const fs = require('fs')
const readerStream = fs.createReadStream('./package.json')
const writerStream = fs.createWriteStream('./test.txt')
readStream.pipe(writeStream)
console.log("执行完成")
zlib
模块,用来处理压缩的功能。
const fs = require('fs')
const zlib = requrie('zlib')
fs.createReadStream('./test.txt').pipe(zlib.createGzip()).pipe(fs.createWriteStream('test.zip'));
// 先压缩文件,然后将文件导出。
console.log('文件压缩成功');