node.js-fs文件系统
异步和同步
同步
:客户端必须等待服务器端的响应,在等待期间客户端不能做其他操作。
异步
:客户端不需要等待服务器的响应,在服务器处理请求的过程中,客户端可以进行其他操作。
Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()。
比起同步,异步方法性能更高,速度更快,而且没有阻塞。在此我只讨论异步的方法。
异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。
异步的形式总是将完成回调作为其最后一个参数。传给完成回调的参数取决于具体方法,但第一个参数始终预留用于异常。如果操作成功完成,则第一个参数是null或undefined。
什么是回调?
所谓“回调”,就是”回头再调”。回调函数并不是马上调用,而是需要等到事件触发了以后再执行
。回调是一个异步等效的功能,在完成特定任务后回调函数被调用。
fs文件系统模块
Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。fs模块是用来操作文件的模块,Node.js 导入文件系统模块(fs)语法如下所示:
const fs = require("fs")
fs.readfile()方法
fs.readfile()方法用于读取指定文件的内容。
基本语法格式:
fs.readFile(path[,options],callback)
● path
:必选参数,字符串类型,表示文件存储路径。
● options
:可选参数,表示读取文件采用的编码格式。
● callback
:必选参数,当文件读取完成后,通过该回调函数拿到读取结果。
实例
如果读取文件成功,那么err的值为null,Datas的值为文件内容
//1.导入文件系统模块
const fs = require('fs')
//2.调用fs.readFile()方法读取文件
fs.readFile('./test.txt', 'utf8', (err, Datas)=>{
console.log(err,Datas);//null 这是一个测试文件。
})
如果文件读取失败,err的值为一个错误对象,Datas的值为undefined
//1.导入文件系统模块
const fs = require('fs')
//2.调用fs.readFile()方法读取文件
fs.readFile('./test1.txt', 'utf8', (err, Datas)=>{
console.log(err,Datas);
/*
[Error: ENOENT: no such file or directory, open 'E:\deyun\node\fs\test1.txt'] {
errno: -4058,
code: 'ENOENT',
syscall: 'open',
path: 'E:\\deyun\\node\\fs\\test1.txt'
} undefined
*/
})
判断文件是否读取成功
我们可以根据err的值判断文件是否读取成功。如果err为null则文件读取成功,否则文件读取失败。
//1.导入文件系统模块
const fs = require('fs')
//2.调用fs.readFile()方法读取文件
fs.readFile('./test.txt', 'utf8', (err, Datas)=>{
if(err){//如果文件读取失败,就打印出错误信息
console.log('文件读取失败。',err)
}else{//读取成功就打印出文件中的信息
console.log(Datas);
}
})
当然我们也可以通过Datas的值判断文件是否读取成功。如果Datas的值为undefined则文件读取失败,否则文件读取成功。
//1.导入文件系统模块
const fs = require('fs')
//2.调用fs.readFile()方法读取文件
fs.readFile('./test.txt', 'utf8', (err, Datas)=>{
if(Datas){//读取成功就打印出文件中的信息
console.log(Datas);
}else{//如果文件读取失败,就打印出错误信息
console.log('文件读取失败。',err)
}
})
fs.writeFile()方法
使用fs.writefile()方法,向指定的文件写入内容。
基本语法格式:
fs.writeFile(file,data[,options],callback)
● file
:必选参数,表示文件存放的路径。
● data
:必选参数,表示写入文件的内容。
● options
:可选参数,表示data数据以什么方式写入文件,默认值为utf8。
● callback
:必选参数,表示文件写入完成后调用的回调函数。
实例
如果文件写入成功err的值为null
,如果文件写入失败err的值为错误对象
//导入fs文件系统模块
const fs = require('fs');
//调用writeFile()函数向文件中写入内容
fs.writeFile('E:/deyun/node/fs/write.txt','Hello word',(err)=>{
console.log(err);
})
判断文件是否写入成功
通过err的值判断文件是否写入成功,如果err的值为null就说明文件写入成功,否则文件写入失败。
//导入fs文件系统模块
const fs = require('fs');
//调用writeFile()函数向文件中写入内容
fs.writeFile('E:/deyun/node/fs/write.txt','Hello word',(err)=>{
if(err){//如果文件写入失败就将错误抛出
throw err;
}else{//如果文件写入成功就打印提示信息
console.log('文件写入成功')
}
})
打开文件fs.open()方法
fs.open()方法用于打开文件。
异步模式下基本语法格式:
fs.open(path, flags[, mode], callback)
● path
:必选参数,表示文件的路径。
● flags
:必选参数,表示文件打开的行为。
● mode
:可选参数,表示设置文件模式(权限),文件创建默认权限为 0666(可读,可写)。
● callback
:必选参数,文件打开完成后调用回调函数。
flags 参数可以是以下值
Flag | 描述 |
---|---|
r | 以读取模式打开文件。如果文件不存在抛出异常。 |
r+ | 以读写模式打开文件。如果文件不存在抛出异常。 |
rs | 以同步的方式读取文件。 |
rs+ | 以同步的方式读取和写入文件。 |
w | 以写入模式打开文件,如果文件不存在则创建。 |
wx | 类似 ‘w’,但是如果文件路径存在,则文件写入失败。 |
w+ | 以读写模式打开文件,如果文件不存在则创建。 |
wx+ | 类似 ‘w+’, 但是如果文件路径存在,则文件读写失败。 |
a | 以追加模式打开文件,如果文件不存在则创建。 |
ax | 类似 ‘a’, 但是如果文件路径存在,则文件追加失败。 |
a+ | 以读取追加模式打开文件,如果文件不存在则创建。 |
ax+ | 类似 ‘a+’, 但是如果文件路径存在,则文件读取追加失败。 |
实例
打开test.txt文件。
//1.导入文件系统模块
const fs = require("fs");
//2.异步打开文件
fs.open('./test.txt', 'r+', (err, fd)=> {
if (err) {//如果打开失败就将错误抛出
throw err
}else{//打开成功就打印提示信息
console.log('文件打开成功');
}
});
获取文件信息fs.stat()方法
异步模式获取文件信息的语法格式:
fs.stat(path, callback)
● path
:必选参数,表示文件路径。
● callback
:必选参数,回调函数,带有两个参数((err, stats), stats 是 fs.Stats 对象)。
stats类中的方法有
方法 | 描述 |
---|---|
stats.isFile() | 如果是文件返回 true,否则返回 false。 |
stats.isDirectory() | 如果是目录返回 true,否则返回 false。 |
stats.isBlockDevice() | 如果是块设备返回 true,否则返回 false。 |
stats.isCharacterDevice() | 如果是字符设备返回 true,否则返回 false。 |
stats.isSymbolicLink() | 如果是软链接返回 true,否则返回 false。 |
stats.isFIFO() | 如果是FIFO,返回true,否则返回 false。FIFO是UNIX中的一种特殊类型的命令管道。 |
stats.isSocket() | 如果是 Socket 返回 true,否则返回 false。 |
实例
获取test.txt文件的信息。
var fs = require("fs");
fs.stat('./test.txt', function (err, stats) {
if (err) {
throw err;
}
console.log(stats);
/*
Stats {
dev: 1352127629,
mode: 33206,
nlink: 1,
uid: 0,
gid: 0,
rdev: 0,
blksize: 4096,
ino: 1688849860277359,
size: 0,
blocks: 0,
atimeMs: 1641973729493.528,
mtimeMs: 1641973729493.528,
ctimeMs: 1641973729493.528,
birthtimeMs: 1641960754449.2866,
atime: 2022-01-12T07:48:49.494Z,
mtime: 2022-01-12T07:48:49.494Z,
ctime: 2022-01-12T07:48:49.494Z,
birthtime: 2022-01-12T04:12:34.449Z
}
*/
console.log("isFile?" + stats.isFile());//isFile?true
console.log("isDirectory?" + stats.isDirectory());//isDirectory?false
});
fs.stat(path)执行后,会将stats类的实例返回给其回调函数。可以通过stats类中的提供方法判断文件的相关属性。例如判断是否为文件,和目录。
读取文件fs.read()方法(按字节读取)
该方法使用了文件描述符来读取文件。
异步模式下读取文件的语法格式:
fs.read(fd, buffer, offset, length, position, callback)
● fd
:必选参数,通过 fs.open() 方法返回的文件描述符。
● buffer
:必选参数,数据写入的缓冲区。
● offset
:必选参数,缓冲区写入的写入偏移量。
● length
:必选参数,要从文件中读取的字节数。
● position
:必选参数,文件读取的起始位置,如果 position 的值为 null,则会从当前文件指针的位置读取。
● callback
:必选参数,回调函数,有三个参数(err, bytesRead, buffer),err 为错误信息, bytesRead 表示读取的字节数,buffer 为缓冲区对象。
实例
按字节读取读取test.txt文件中的内容。
const fs = require("fs");
const buf = Buffer.alloc(1024);
fs.open('test.txt', 'r+', (err, fd)=>{
if (err) {
throw err;
}else{
console.log("文件打开成功!");
}
//准备读取文件
fs.read(fd, buf, 0, buf.length, 0,(err, bytes)=>{
if (err){
console.log(err);
}else{
console.log('文件读取成功:'+bytes+ "字节被读取");//文件读取成功:24字节被读取
}
// 仅输出读取的字节
if(bytes > 0){
console.log(buf.slice(0, bytes).toString());//这是一个测试文件
}
});
});
关闭文件fs.close()方法
异步模式下关闭文件的语法格式:
fs.close(fd, callback)
● fd
:必选参数,通过 fs.open() 方法返回的文件描述符。
● callback
:必选参数,回调函数。
实例
先打开test.txt文件,在关闭test.txt文件。
const fs = require("fs");
//打开文件
fs.open('test.txt', 'r+', (err, fd)=>{
if (err) {
throw err;
}else{
console.log("文件打开成功!");
}
//关闭文件
fs.close(fd,(err)=>{
if (err){
console.log(err);
}
console.log("文件关闭成功!");
});
});
截取文件fs.ftruncate()方法
该方法用于截取指定字节内的文件内容,超出部分将被去除。
异步模式下截取文件的语法格式:
fs.ftruncate(fd, len, callback)
● fd
:必选参数,通过 fs.open() 方法返回的文件描述符。
● len
:必选参数,文件内容截取的长度。
● callback
:必选参数,回调函数。
实例
我们截取了12字节的内容,由于一个汉字占3字节,因此有截取了4个汉字,其余部分被去除。
const fs = require("fs");
const buf = Buffer.alloc(1024);
//打开文件
fs.open('test.txt', 'r+', (err, fd) => {
if (err) {
throw err;
} else {
console.log("文件打开成功!");
}
// 截取文件
fs.ftruncate(fd, 12, function (err) {
if (err) {
console.log(err);
}
//读取截取后的文件
fs.read(fd, buf, 0, buf.length, 0, function (err, bytes) {
if (err) {
console.log(err);
}
// 仅输出读取的字节
if (bytes > 0) {
console.log(buf.slice(0, bytes).toString());//这是一个
}
});
});
});
文件复制fs.copyFile()函数
将原文件的内容复制到目标文件,目标文件的内容会被覆盖。
基本语法格式:
fs.copyFile(file1,file2,callback)
● file1
:必选参数,原文件。
● file2
:必选参数,目标文件。
● callback
:必选参数,回调函数。
实例
将test.txt文件中的内容复制到write.txt中。
const fs = require('fs');
fs.copyFile('./test.txt', './write.txt', (err) => {
if (err) {
throw err;
}
console.log('文件复制成功')
})
向文件末尾添加内容fs.appendFile()方法
基本语法格式:
fs.appendFile(filename,content,callback)
● filename
:必选参数,文件名(含路径)。
● content
:必选参数,要添加的内容。
● callback
:必选参数,回调函数。
实例
向test.txt文件内容的末尾添加“测试文件”。
const fs = require('fs');
fs.appendFile('./test.txt', '测试文件', (err) => {
if (err) {
throw err;
}
console.log('追加内容成功')
})
删除文件fs.unlink()方法
基本语法格式:
fs.unlink(path, callback)
● path
:必选参数,文件路径。
● callback
:必选参数,回调函数。
实例
删除test.txt文件。
var fs = require("fs");
fs.unlink('./test.txt', (err)=>{
if (err) {
throw err;
}
console.log("删除成功");
});
重命名fs.rename()方法
基本语法格式:
fs.rename(oldPath, newPath, callback)
● oldPath
:必选参数,原文件名(含路径)。
● newPath
:必选参数,新文件名(含路径)。
● callback
:必选参数,回调只有一个可能的异常参数。
实例
将当前路径下的write.txt改名为test.txt。
var fs = require("fs");
fs.rename('./write.txt', './test.txt', (err)=>{
if(err){
throw err
}
console.log('文件名更改成功')
})
创建目录
创建目录的语法格式:
fs.mkdir(path[, options], callback)
● path
:必选参数,文件路径。
● options
:可选参数,参数可以是:recursive - 是否以递归的方式创建目录,默认为 false。mode - 设置目录权限,默认为 0777。
● callback
:必选参数,回调函数。
实例
创建一个tmp文件。
var fs = require("fs");
fs.mkdir('./tmp', function (err) {
if (err) {
throw err;
}
console.log("目录创建成功");
});
读取目录
读取目录的语法格式:
fs.readdir(path, callback)
● path
:必选参数,文件路径。
● callback
:必选参数,回调函数,回调函数带有两个参数(err, files),err 为错误信息,files 为 目录下的文件数组列表。
实例
读取当前路径下的文件列表。
const fs = require("fs");
fs.readdir("./",(err, files)=>{
if (err) {
throw err;
}
console.log(files);
/*
[
'addpenfile.js', 'copyfile.js',
'mkdirk.js', 'open.js',
'readFile.js', 'reddir.js',
'rename.js', 'stat.js',
'tmp', 'unlink.js',
'write.js', 'writeFile.js'
]
*/
});
删除目录
删除目录的语法格式:
fs.rmdir(path, callback)
● path
:必选参数,文件路径。
● callback
:必选参数,回调函数,没有参数。
实例
删除tmp。
var fs = require("fs");
fs.rmdir("./tmp",(err)=>{
if (err) {
throw err;
}
console.log('删除文件路径成功');
});