Node.js学习二(fs 文件系统)


一、什么是fs文件系统模块

fs模块是Node.js官方提供的,用来操作文件的模块。它提供了一系列的方法和属性,用来满足用户对文件的操作需求。

使用fs模块操作文件时,需要先导入它,代码如下:

const fs = require(‘fs’)

二、同步与异步

(1)同步:程序在涉及到文件IO时,必须等到文件IO操作结束后再执行后续的操作。

(2)异步:程序在涉及到文件IO时,不等待文件IO操作结束,继续执行后续的操作,当文件IO操作结束后系统会通知程序处理文件IO的结果。

所有文件系统操作都具有同步和异步形式,供开发者选择。
异步的形式总是将完成回调作为其最后一个参数。传给完成回调的参数取决于具体方法,但第一个参数始终预留用于异常。如果操作成功完成,则第一个参数是null或undefined。

三、回调函数

所谓“回调”,就是”回头再调”。回调函数并不是马上调用,而是需要等到事件触发了以后再执行。回调是一个异步等效的功能,在完成特定任务后回调函数被调用。

四、读取指定文件中的内容

1、fs.readFile()

用于异步读取数据。 - - - - 也叫非阻塞方式读

语法格式如下:

fs.readFile(path[,options],callback);

path:必选参数,字符串,表示文件的路径,可以是绝对路径,也可以是相对路径。注意,如果是相对路径,是相对于当前进程所在的路径(process.cwd()),而不是相对于当前脚本所在的路径。
option:可选参数,表示以什么编码格式来读取文件
callback:必选参数,文件读取完成后,通过回调函数拿到读取的结果,该函数的第一个参数是发生错误时的错误对象,第二个参数是代表文件内容的Buffer实例。
举例如下:

//导入fs模块
const fs = require('fs');
//调用readFile()方法读取文件
fs.readFile('./fs1.txt','utf8',function(err,dataStr){
   	console.log(err);
   	console.log('-----');
   	console.log(dataStr);
});
console.log('异步读取文件')
//err代表打印失败后的结果,dataStr代表打印成功后的结果

成功时的结果如下:
在这里插入图片描述

此时err为null,dataStr为打印出的结果,且我们可以发现,先打印出了“异步读取文件”的结果,这就可以看出fs.readFile()用于异步读取数据的特性,在涉及到文件IO时,它不等待文件IO操作结束,会继续执行后续的操作,当文件IO操作结束后系统会通知程序处理文件IO的结果。

失败后的结果如下,此时我们故意写一个错误的文件名。

//导入fs模块
const fs = require('fs');
//调用readFile()方法读取文件
fs.readFile(__dirname+'/fs2.txt','utf8',function(err,dataStr){
    console.log(err);
    console.log('-----');
    console.log(dataStr);
});
console.log('异步读取文件')
//err代表打印失败后的结果,dataStr代表打印成功后的结果

在这里插入图片描述
则err会打印出错误对象,dataStr结果为undefined

2、判断文件是否读取成功

可以通过err对象是否为null,从而判断文件读取的结果。

//判断文件是否读取成功
//导入fs模块
const fs = require('fs');
fs.readFile('./fs1.txt','utf8',function (err,result){
    if(err){
        console.log('读取失败:'+err.message)
    }else{
        console.log('读取成功')
        console.log(result)
    }
})

读取成功时打印结果如下:
在这里插入图片描述

读取失败时结果如下:
在这里插入图片描述

3、readFileSync()

用于同步读取文件,返回一个字符串。- - - -阻塞方式

语法格式如下:

fs.readFileSync(path[, options]);

readFileSync方法的第一个参数是文件路径,第二个参数可以是一个表示配置的对象,也可以是一个表示文本文件编码的字符串。默认的配置对象是{ encoding: null, flag: ‘r’ },即文件编码默认为null,读取模式默认为r(只读)。如果第二个参数不指定编码(encoding),readFileSync方法返回一个Buffer实例,否则返回的是一个字符串。
举例如下:

//同步读取文件
const fs = require('fs');
const str = fs.readFileSync('./fs1.txt','utf8');
console.log(str);
console.log('同步读取文件');

结果如下:
在这里插入图片描述

可以发现它同步方式处理数据的特性,先等待文件IO操作结束,返回其结果,再接着往下处理程序。

五、向指定的文件中写入内容

1、fs.writeFile()

异步写入文件,如果文件已经存在将会覆盖文件
语法格式:

fs.writeFile(file,data[,option],callback);

file:必选参数,需要指定一个文件路径的字符串,表示文件的存放路径
data:必选参数,表示要写入的内容
option:可选参数,表示以什么格式写入文件内容,默认值是utf8
callback:必选参数,文件写入完成后的回调函数,回调函数获取一个参数err,用于在发生任何写入错误时返回错误。
举例如下:

//导入fs模块
const fs = require('fs');
//调用fs.writeFile()方法,写入文件的内容
fs.writeFile('f://ds','我爱北京天安门','utf8',function (err){
    if(err){
        console.log('写入失败:'+err.message)
    }else{
        console.log('写入成功')
        fs.readFile('./fs1.txt','utf8',function (e,result){
            if(e){
                return '读取失败'+e.message
            }else{
                console.log(result)
            }
        })
    }
})

在上述代码中,我们指定写入文件的路径在f盘里,可是本电脑是没有f盘的,所以写入失败,打印出错误信息。
在这里插入图片描述

//导入fs模块
const fs = require('fs');
//调用fs.writeFile()方法,写入文件的内容
fs.writeFile('./fs1.txt','我爱北京天安门','utf8',function (err){
    if(err){
        console.log('写入失败:'+err.message)
    }else{
        console.log('写入成功')
		console.log('此时的错误为:',err)
        fs.readFile('./fs1.txt','utf8',function (e,result){
            if(e){
                console.log('读取失败'+e.message)
            }else{
                console.log(result)
            }
        })
    }
})

这个代码路径正确,按照程序来讲,它会打印出写入成功,然后打印出当成功时err被定义为null,最后读取出写入的信息
在这里插入图片描述

2、判断文件是否写入成功

可以判断err对象是否为null,来判断文件是否写入成功。

//导入fs模块
const fs = require('fs');
//调用fs.writeFile()方法,写入文件的内容
fs.writeFile('f://fs1.txt','天安门上太阳升',function (err){
    if(err){
        return console.log('文件写入失败:'+err)
    }else{
        console.log('文件写入成功')
    }
});

此时错误,err就会被打印出:
在这里插入图片描述

六、案例:信息整理

我们有一个old.txt文件,里面的内容为:
小熊-蜂蜜 小狗-牛奶 小猫-小鱼 小柳-阳光
现在想把它整理后放入新文件new.txt中。整理后的内容为:
小熊:蜂蜜
小狗:牛奶
小猫:小鱼
小柳:阳光
步骤如下:
1、导入fs模块
2、使用readFile()方法,读取old.txt的内容
3、判断文件是否读取成功
4、读取成功后,处理内容
5、处理完成后,使用writeFile()方法,将内容写入到新文件new.txt中
代码如下:

//导入fs模块
const fs = require('fs');
//使用readFile()方法,读取old.txt里的内容
fs.readFile('./old.txt','utf8',function (err,result){
    if(err){
        console.log('读取失败:',err)
    }else{
        //处理读取到的数据
        //先从空格处分隔字符串,使它成为数组
        const newtxt = result.split(' ');
        //遍历数组,且将每个数据中的-替换为:
        const as = [];
        for(let k of newtxt){
            const b = k.replace('-',':');
            as.push(b)
        }
        //将替换后的数组转换为字符串,且每一项之间换行
        const str = as.join('\n');
        //将处理好的文件通过writeFile()方法写入new.txt中
        fs.writeFile('./new.txt',str,function (err){
            if(err){
                return console.log('写入失败')
            }else{
                console.log('写入成功')
            }
        })
    }

在这里插入图片描述
在这里插入图片描述

七、fs模块-路径动态拼接的问题

在使用fs模块操作文件时,如果提供的操作路径是以./或…/开头的相对路径时,很容易出现路径动态拼接错误的问题,原因是代码在运行的时候,会以执行node命令时所处的目录,动态拼接出被操作文件的完整路径。
解决方案1:在使用fs模块操作文件时,直接提供完整的路径,不要提供./或…/开头的相对路径,从而防止路径动态拼接的问题。
注意:在js中,一个\的意思是转义,连个\才代表斜线的意思,所以完整路径要写为:

C:\\Users\\ace23\\Documents

这种方法的缺点是移植性差,且不利于维护,路径较长时,一处写错会很麻烦
解决方案2:__dirname+’路径’:__dirname表示当前文件所处的目录
如:

const fs = require('fs');
fs.readFile(__dirname+'/fs1.txt','utf8',function (err,result){
    if(err){
        console.log('读取失败:'+err.message)
    }else{
        console.log('读取成功')
        console.log(result)
    }
})

在这里插入图片描述

八、打开一个文件

在异步模式下打开文件的语法是:

fs.open(path[, flags[, mode]], callback);

path - 文件名,包括路径字符串。
flags - 标志要打开的文件的方式,默认值: ‘r’。flags参数的常用取值:
–‘r’:以只读方式打开文件,若文件不存在则报异常
–‘w’:打开文件进行写入,若文件不存在则创建文件
–‘a’:向文件中追加内容,若文件不存在则创建文件
–‘rs’:同步方式打开文件
mode - 设置文件模式,但前提是已创建该文件。它默认为0666,可读取和写入。
callback - 这是回调函数,有两个参数(err, fd)。
举例如下:

//打开文件
const fs = require('fs');
fs.open(__dirname+'/fs1.txt',function (err,fd){
   		fs.readFile('./fs1.txt','utf8',function (err,data){
       		console.log(data)
   		})
   		console.log('打开文件成功');
   		console.log(fd);
});

结果如下:
在这里插入图片描述

九、获取文件信息

它产生一个对象,该对象包含了该文件或目录的具体信息。通过该方法,判断正在处理的是一个文件,还是一个目录。语法格式如下:

fs.stat(path[, options], callback);

参数的说明:
path - 文件名,包括路径字符串。
options - bigint 返回的 <fs.Stats> 对象中的数值是否应为 bigint。默认值: false。
callback - 回调函数得到两个参数(err, stats) 。其中stats 是 <fs.Stats> 对象,表示文件的状态信息。
我们还可以通过stats的isFile()与isDirectory()方法判断文件是否为文件格式或者文件夹格式。
举例如下:

//获取文件信息
const fs = require('fs');
fs.stat('./fs1.txt',function (err,stats){
   		if(err){
       		return console.log(err);
   		}
   		console.log(stats);
   		console.log(stats.isFile());
});

结果如下:
在这里插入图片描述

十、创建目录

fs.mkdir(path[, mode], callback);

参数说明:
path - 包括路径的目录名。
mode - 要设置的目录权限,默认是可读可写。
callback - 回调函数
举例如下:

//创建目录
const fs = require('fs');
fs.mkdir('./study',function (err){
  		 if(err){
       		return console.log(err);
   		}
   		console.log('目录创建成功');
});

十一、删除目录

fs.rmdir(path, callback);

参数说明:
path - 包括路径的目录名。
callback - 回调函数
举例如下:

//删除目录
const fs = require('fs');
fs.rmdir('./study',function (err){
   		if(err){
       		return console.log(err);
   		}
   		console.log('目录删除成功');
});

十二、读取目录

fs.readdir(path, callback);

参数说明:
path - 包括路径的目录名。
callback - 回调函数,两个参数(err, files),其中文件的文件名的目录中的数组排除 ‘.’ 和 ‘…’,'files’是列表,当中放的是当前目录下的文件或文件夹名称。
举例如下:

//读取目录
const fs = require('fs');
fs.readdir('./',function (err,file){
    if(err){
        return console.log(err);
    }
    console.log(file);
})

结果如下:
在这里插入图片描述


版权声明:本文为qq_44872688原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。