当前位置: 首页 > 后端技术 > Node.js

nodejs中的文件系统

时间:2023-04-03 18:21:04 Node.js

简介Nodejs使用异步IO来提高服务器的处理效率。IO的一个很重要的方面就是文件IO。今天我们就来详细介绍下nodejs中的文件系统和IO操作。nodejs中的文件系统模块nodejs中有一个非常重要的模块,叫做fs。该模块提供了许多非常有用的功能,用于访问文件系统并与之交互。简单统计,fs提供了以下文件操作方法:fs.access():检查文件是否存在,Node.js是否有访问权限。fs.appendFile():将数据附加到文件。如果该文件不存在,则创建该文件。fs.chmod():更改文件的权限(由传递的文件名指定)。相关方法:fs.lchmod()、fs.fchmod()。fs.chown():更改文件的所有者和组(由传递的文件名指定)。相关方法:fs.fchown()、fs.lchown()。fs.close():关闭文件描述符。fs.copyFile():复制一个文件。fs.createReadStream():创建可读文件流。fs.createWriteStream():创建可写文件流。fs.link():创建指向文件的新硬链接。fs.mkdir():创建一个新文件夹。fs.mkdtemp():创建一个临时目录。fs.open():设置文件模式。fs.readdir():读取目录的内容。fs.readFile():读取文件内容。相关方法:fs.read()。fs.readlink():读取符号链接的值。fs.realpath():将相对文件路径指针(.,..)解析为完整路径。fs.rename():重命名文件或文件夹。fs.rmdir():删除文件夹。fs.stat():返回文件的状态(由传递的文件名指定)。相关方法:fs.fstat()、fs.lstat()。fs.symlink():指向新创建文件的符号链接。fs.truncate():将传递的文件名标识的文件截断到指定长度。相关方法:fs.ftruncate()。fs.unlink():删除文件或符号链接。fs.unwatchFile():停止监视文件的更改。fs.utimes():更改文件的时间戳(由传递的文件名指定)。相关方法:fs.futimes()。fs.watchFile():开始监视文件的变化。相关方法:fs.watch()。fs.writeFile():将数据写入文件。相关方法:fs.write()。注意上面fs提供的方法都是异步的。所谓异步,就是这些方法提供了回调函数,方便异步触发相应的处理逻辑。让我们举一个读取文件的简单例子:constfs=require('fs')fs.readFile('/tmp/flydean.txt','utf8',(err,data)=>{if(err){console.error(err)return}console.log(data)})在上面的示例中,我们从/tmp文件中读取了一个flydean.txt文件。并在回调函数中分别处理异常和正常数据。fs在提供异步方法的同时,也提供了同步方法调用。这个同步方法是在异步方法之后加上Sync:constfs=require('fs')try{constdata=fs.readFileSync('/tmp/flydean.txt','utf8')console.log(data)}catch(err){console.error(err)}看看把上面的方法改写成同步方法后的样子。两者的区别是同步方式会阻塞等待,直到文件读取完成。fs的Promise版本的异步操作怎么会比不上Promsie,因为fs中的操作都是异步的,如果不想通过callback使用fs,fs也提供了Promise版本。还是刚才readfile的例子,我们看看如果使用Promise会怎样:constfs=require('fs/promises');(asyncfunction(path){try{awaitfs.readFile(path,'utf8');console.log(`成功读取文件${path}`);}catch(error){console.error('error:',error.message);}})('/tmp/flydean.txt');fs的promise版本在fs/promises下。在上面的例子中,我们使用了async和await来以同步的方式编写异步程序,非常方便。文件描述符文件描述符是指我们在nodejs中使用fs.open方法时得到的返回值。我们可以使用这个文件描述符来处理文件并与之交互。constfs=require('fs')fs.open('/tmp/flydean.txt','r',(err,fd)=>{//fd是一个文件描述符。})open方法的第一个上面两个参数表示以只读方式打开文件。让我们看看常用的文件系统标志:'r':打开文件进行读取。如果文件不存在,则会发生异常。'r+':打开文件进行读写。如果文件不存在,则会发生异常。'w':打开文件进行写入。如果文件不存在则创建文件,如果文件存在则截断文件。'w+':打开文件进行读写。如果文件不存在则创建文件,如果文件存在则截断文件。'a':打开文件进行追加。如果该文件不存在,则创建它。'a+':打开文件进行读取和追加。如果该文件不存在,则创建它。当然,上面的例子也可以用openSync重写:constfs=require('fs')try{constfd=fs.openSync('/tmp/flydean.txt','r')}catch(err){console.error(err)}fs.stat文件状态信息nodejs提供了一个fs.Stats类来描述文件的状态信息。Stats提供了一些非常有用的方法来判断文件的状态:例如:stats.isDirectory()、stats.isFile()、stats.isSocket()、stats.isSymbolicLink()、stats.ctime等。stats还提供一些与文件时间相关的选项:atime"accesstime"-上次访问文件数据的时间。mtime"modifiedtime"-最后一次修改文件数据的时间。ctime"changetime"-最后一次文件状态改变的时间(inode数据的修改)。birthtime"creationtime"-文件的创建时间。让我们看看如何获??取fs.stat:constfs=require('fs')fs.stat('/tmp/flydean.txt',(err,stats)=>{if(err){console.error(err)return}stats.isFile()//truestats.isDirectory()//falsestats.isSymbolicLink()//falsestats.size//文件大小})fs.Stats会作为fs.stat的回调函数参数传入进入。通过fs.Stats,我们再进行一系列的操作。fs文件的读写上面我们介绍了使用fs进行文件读取操作。接下来介绍如何使用fs进行文件写入操作:constfs=require('fs')constcontent='www.flydean.com'fs.writeFile('/tmp/flydean.txt',content,err=>{if(err){console.error(err)return}//文件写入成功})以上是回调版本,我们再来看一个同步版本:constfs=require('fs')constcontent='www.flydean.com'try{constdata=fs.writeFileSync('/tmp/flydean.txt',content)//文件写入成功。}catch(err){console.error(err)}writeFile还支持一个额外的选项参数。在options参数中,我们可以指定文件写入的标志位,如:r+、w+、a、a+等。fs.writeFile('/tmp/flydean.txt',content,{flag:'a+'},err=>{})当然fs除了用a+表示追加到文件末尾外,还提供了appendFile方法输出到文件末尾:constfs=require('fs')constcontent='www.flydean.com'fs.appendFile('/tmp/flydean.txt',content,err=>{if(err){console.error(err)return}//文件追加成功。})fs的文件夹操作有文件和文件夹,fs提供了一系列文件夹操作,如:mkdir、readdir、renamermdir操作。readdir相对负责。让我们用一个例子来说明:constfs=require('fs')constfolderPath='/tmp'fs.readdir(folderPath,function(err,files){if(err){console.log(err);}文件。map(file=>console.log(file));})fs.readdirSync(folderPath).map(fileName=>{console.log(fileName);})在上面的例子中,我们使用readdir有两种方式和readdirSync读取目录中的文件。你可以看到差异。路径操作最后,我们介绍一个特定于文件的路径操作,它提供了一些用于处理文件和目录路径的实用程序。path表示路径。我们通过以下方式使用路径:constpath=require('path')为什么我们需要路径?我们知道,这个世界上大约有两种风格的操作系统,windows和POSIX。路径在两个操作系统中的表达方式不同。所以,我们需要一个通用的路径模块来为我们解决这个差异。我们可以通过示例观察这种差异:在Windows上:path.basename('C:\\temp\\myfile.html');//returns:'myfile.html'onPOSIX:path.basename('C:\\temp\\myfile.html');//Return:'C:\\temp\\myfile.html'我们来看看首先在path.basename方法中,用于返回路径的最后一部分。在上面的例子中,我们给windows传递了一个windows风格的路径,所以可以正常解析,也可以得到正常的结果。在POSIX环境下,我们传入一个windows风格的路径,无法正常解析,直接返回整个结果。path还有很多有用的方法,比如:constnotes='/tmp/notes.txt'path.dirname(notes)///tmppath.basename(notes)//notes.txtpath.extname(notes)//。txtpath.join('/','tmp','notes.txt')//'/tmp/notes.txt'path.resolve('notes.txt')//'/Users/flydean/notes.txt'从当前目录开始解析,获取相对路径的绝对路径path.normalize('/tmp/flydean..//test.txt')///tmp/test.txt尝试计算出实际路径本文作者文章:flydean程序那些事儿本文链接:http://www.flydean.com/nodejs-file-system/本文来源:flydean的博客欢迎关注我的公众号:《程序》最流行解读,最深奥的干货,最简洁的更多教程,很多你不知道的小技巧等你来发现!