Nodejs学习item 4 -- 文件系统file

本文详细介绍了Node.js文件系统的各种操作方法,包括文件的读写、目录的创建与读取等核心功能,并提供了丰富的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Node.js 文件系统

Node.js 提供一组类似 UNIX(POSIX)标准的文件操作API。 Node 导入文件系统模块(fs)语法如下所示:

var fs = require("fs")

1. 异步和同步

Node.js 文件系统(fs 模块)模块中的方法均有异步和同步版本,例如读取文件内容的函数有异步的 fs.readFile() 和同步的 fs.readFileSync()
异步的方法函数最后一个参数为回调函数,回调函数的第一个参数包含了错误信息(error)。

建议大家是用异步方法,比起同步,异步方法性能更高,速度更快,而且没有阻塞,但遇到像加载一些配置文件的时候,为了保证文件的顺序,则使用同步的放方法。

2. 文件完整的读写

fs.readFile(file[, options], callback)–读取整个文件

  • file <String> | <Integer> filename or file descriptor:文件路径名或者文件的描述
  • options <Object> | <String>
    • encoding <String> | <Null> default = null
    • flag <String> default = 'r'
  • callback <Function>:回调函数 function(err,data)
fs.readFile('/etc/passwd', (err, data) => {
  if (err) throw err;
  console.log(data);
});
fs.readFile('/etc/passwd', 'utf8', callback);

fs.writeFile(file, data[, options], callback)

  • file <String> | <Integer> filename or file descriptor
  • data <String> | <Buffer>
  • options <Object> | <String>
    • encoding <String> | <Null> default = ‘utf8’
    • mode <Number> default = 0666
    • flag <String> default = ‘w’
  • callback <Function>
fs.writeFile('message.txt', 'Hello Node.js', (err) => {
  if (err) throw err;
  console.log('It\'s saved!');
});
fs.writeFile('message.txt', 'Hello Node.js', 'utf8', callback);

一个完整的读写操作:

var fs = require('fs');
var txt = "以上程序使用fs.readFileSync从源路径读取文件内容,并使用fs.writeFileSync将文件内容写入目标路径。";

//写入文件
fs.writeFile('message.txt', txt, function (err) {
    if (err) throw err;
    console.log('It\'s saved!'); //文件被保存
});

//读取文件
fs.readFile('message.txt', 'utf8', function (err, data) {
    if (err) throw err;
    console.log(data);
});

读取文件编码一定要写,不然会读出原生buffer。

3. 从指定位置开始读取文件

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

  • path 为文件的路径,
  • flags 可以是以下值。
     r :以读取模式打开文件。
     r+ :以读写模式打开文件。
     w :以写入模式打开文件,如果文件不存在则创建。
     w+ :以读写模式打开文件,如果文件不存在则创建。
     a :以追加模式打开文件,如果文件不存在则创建。
     a+ :以读取追加模式打开文件,如果文件不存在则创建。
  • mode 参数用于创建文件时给文件指定权限,默认是 0666。回调函数将会传递一个文 件描述符 fd。
var fs=require('fs');
fs.open('./message.txt','r',function(err,fd) {
    console.log(fd);
})

fs.read(fd, buffer, offset, length, position, callback)

  • fd: open 打开的中回调函数的fd,表示一个文件描述符.

  • buffer:一个Buffer对象,将文件数据读取到那个缓冲区。

  • offset:从缓冲区哪里开始写入.

  • length:从文件中读取的字节数.

  • position:从文件那个位置开始读。

  • callback:function (err, bytesRead, buffer).

    • err: 发生错误,byteRead,实际读取的文件字节数,position+length可能大于文件的字节数,buffer 被读取的缓冲对象
var fs=require('fs');//message.txt="我喜爱编程";
fs.open('./message.txt','r',function(err,fd) {
    var buf=new Buffer(255);
    //一个汉字的utf编码为三个字节数据
    fs.read(fd,buf,0,9,3,function(err, bytesRead, buffer){
        console.log(buffer.slice(0,bytesRead).toString());
    });//喜爱编
})

position如果设置为null,则从上次读的位置接着往下读。

var fs=require('fs');
fs.open('./message.txt','r',function(err,fd) {
    var buf=new Buffer(255);
    //一个汉字的utf编码为三个字节数据
    fs.read(fd,buf,0,9,3,function(err, bytesRead, buffer){
        console.log(buffer.slice(0,bytesRead).toString());
        //结果:喜爱编。从文件的当前读取位置继续往下读取
        fs.read(fd,buf,0,3,null,function(err, bytesRead, buffer){
            console.log(buffer.slice(0,bytesRead).toString());
        });//程
    });
})
  • fs.write(fd, buffer, offset, length[, position], callback)
    fs.write将buffer缓冲器内容写入fd文件描述符,

  • offset和length决定了将缓冲器中的哪部分写入文件。

  • position指明将数据写入文件从头部算起的偏移位置,若position为null,数据将从当前位置开始写入
  • callback 回调函数接受两个参数(err, written),其中written标识有多少字节的数据已经写入

注意:写完后要关闭它

var fs=require('fs');
fs.open('./message.txt','r',function(err,fd) {
    var buf=new Buffer(255);
    //一个汉字的utf编码为三个字节数据
    var bytesRead=fs.readSync(fd,buf,0,9,3);
    console.log(bytesRead);
    console.log(buf.slice(0,bytesRead).toString());
})

追加写入:

var fs=require('fs');
var buf=new Buffer('我喜爱编程');
fs.open('./message.txt','a',function(err,fd) {
    fs.write(fd,buf,3,9,0,function(err,written,buffer) {
        fs.write(fd,buf,12,3,null,function(err,written,buffer) {
            if(err) console.log("写文件操作失败。");
            else console.log("写文件操作成功。"); 
        }); 
    });
})
  • fs.close(fd, [callback]):关闭文件,有open,就有关闭
var fs=require('fs');
var buf=new Buffer('我喜爱编程');
fs.open('./anotherMessage.txt','wx',function(err,fd) {
    fs.write(fd,buf,0,15,0,function(err,written,buffer) {
        if(err) console.log("写文件操作失败。");
        else console.log("写文件操作成功。");
        fs.close(fd); 
    });
})
  • fs.fsync(fd, [callback]):确保缓冲区的文件全部被写入,close之前。
var fs=require('fs');
var buf=new Buffer('我喜爱编程');
fs.open('./anotherMessage.txt','wx',function(err,fd) {
    fs.write(fd,buf,0,15,0,function(err,written,buffer) {
        if(err) console.log("写文件操作失败。");
        else console.log("写文件操作成功。");
        fs.fsync(fd);
        fs.close(fd); 
    });
})

4、创建于读取目录

创建目录
以下为创建目录的语法格式:

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

参数使用说明如下:

  • path - 文件路径。
  • mode - 设置目录权限,默认为 0777。
  • callback - 回调函数,没有参数。
var fs = require("fs");

console.log("创建目录 /tmp/test/");
fs.mkdir("/tmp/test/",function(err){
   if (err) {
       return console.error(err);
   }
   console.log("目录创建成功。");
});

以上代码执行结果如下:

$ node file.js 
创建目录 /tmp/test/
目录创建成功。

读取目录

以下为读取目录的语法格式:

fs.readdir(path, callback)

参数使用说明如下:

  • path - 文件路径。
  • callback - 回调函数,回调函数带有两个参数err, files,err 为错误信息,- files 为 目录下的文件数组列表。
var fs = require("fs");

console.log("查看 /tmp 目录");
fs.readdir("/tmp/",function(err, files){
   if (err) {
       return console.error(err);
   }
   files.forEach( function (file){
       console.log( file );
   });
});

以上代码执行结果如下:

$ node file.js 
查看 /tmp 目录
input.out
output.out
test
test.txt

删除目录

以下为删除目录的语法格式:

fs.rmdir(path, callback)

参数使用说明如下:

  • path - 文件路径。
  • callback - 回调函数,没有参数。
var fs = require("fs");

console.log("准备删除目录 /tmp/test");
fs.rmdir("/tmp/test",function(err){
   if (err) {
       return console.error(err);
   }
   console.log("读取 /tmp 目录");
   fs.readdir("/tmp/",function(err, files){
      if (err) {
          return console.error(err);
      }
      files.forEach( function (file){
          console.log( file );
      });
   });
});

以上代码执行结果如下:

$ node file.js 
准备删除目录 /tmp/test
input.out
output.out
test
test.txt
读取 /tmp 目录

……

5. 其他一些操作

  • fs.rename(path1, path2, [callback]),fs.renameSync(path1, path2)
    重命名某个文件,前者异步调用,后者同步调用。除非回调函数执行过程出现了异常,否则不会传递任何参数。 例如:
var fs=require('fs');
fs.rename('D:/test.js','D:/test1.js',function(err){
    if(err){
       console.log(err);  
    }else{
       console.log('renamed complete');
     }
})
  • fs.truncate(fd,len,[callback]),fs.trucateSync(fd,len)

    异步调用截断某个文件,如果执行过程中出现异常,回调函数接收一个参数(err),否则不传递任何参数。

var fs=requrie('fs');
fs.open('../test.js',function(err,fd){
    fs.truncate('../test.js',10,function(err){
        if(err){
            throw err;
        }
        console.log(fd);
    });    
});

fs.stat(path, [callback]),
fs.lstat(path, [callback]),
fs.fstat(fd, [callback])fs.statSync(path)、fs.lstatSync(path)、fs.fstatSync(fd)

读取文件元信息,回调函数将返回两个参数(err, stats),其中stats是fs.Stats的一个对象.者的区别在于:

第一个是返回文件的信息,参数是路径
第二个是和第一个一样,当路径是文件链接时,返回这个链接文件的信息
第三个是传递参数为fd文件描述符

fs.link(srcpath, dstpath, [callback])、fs.linkSync(srcpath, dstpath) 和 fs.symlink(linkdata, path, [callback])、fs.symlinkSync(linkdata, path)

建立文件链接,除非回调函数执行过程出现了异常,否则不会传递任何参数。link和symlink的区别是: link 创建的是hard link 所谓硬链接 symlink创建的是symbolic link 所谓符号链接 硬链接就是备份,软连接就是快捷方式

fs.readlink(path, [callback])、fs.realpath(path, [callback]) 、fs.unlink(path, [callback])和 fs.readlinkSync(path)、fs.realpathSync(path)、fs.unlinkSync(path)

异步调用readlink,回调函数返回两个参数(err,resolvedPath),resolvedPath为解析后的文件路径。 这3个函数分别是:
1、readlink:读取链接源地址
3、unlink:删除某一个文件链接

fs.rmdir(path, [callback])、
fs.mkdir(path, mode, [callback])、

fs.readdir(path, [callback]) 和 fs.rmdirSync(path)、fs.mkdirSync(path, mode)、fs.readdirSync(path)

三个命令分别是: rmdir:删除目录 mkdir:建立目录 readdir:读取目录中的内容。回调函数接受两个参数(err, files),其中files参数是保存了目录中所有文件名的数组(’.’和’..’除外)。

fs.watchFile监听指定文件filename的变化,回调函数listener将在每次该文件被访问时被调用.

第二个参数[options]是可选项,如果指定了options参数,它应该是一个包含如下内容的对象:名为persistent的布尔值,和名为interval单位为毫秒的轮询时间间隔,默认值为{ persistent: true, interval: 0 }。 listener监听器将获得两个参数(curr, prev),分别标识当前的状态对象和改变前的状态对象,这些状态对象为fs.Stat的实例。
fs.unwatchFile停止监听文件filename的变化。

fs.Stats

fs.stat()和 fs.lstat()方法返回的对象为此类型

  • stats.isFile()
  • stats.isDirectory()
  • stats.isBlockDevice()
  • stats.isCharacterDevice()
  • stats.isSymbolicLink() (only valid with fs.lstat()) stats.isSymbolicLink() (仅对fs.lstat()有效)
  • stats.isFIFO()
  • stats.isSocket()
{ dev: 2049,
  ino: 305352,
  mode: 16877,
  nlink: 12,
  uid: 1000,
  gid: 1000,
  rdev: 0,
  size: 4096,
  blksize: 4096,
  blocks: 8,
  atime: '2009-06-29T11:11:55Z',
  mtime: '2009-06-29T11:11:40Z',
  ctime: '2009-06-29T11:11:40Z' }
在Node.js中,可以使用iconv-lite库来处理UTF-8编码。iconv-lite是一个纯JS实现的库,支持多种编码格式,包括UTF-8。 下面是一个从GBK文件读取内容,然后将编码转存为UTF-8编码的例子: ``` var buffer = Buffer.from(fs.readFileSync('gbkFile.txt',{encoding:'binary'}),'binary'); console.log(buffer);//得到文件内容对应的Buffer var text = iconv.decode(buffer,'GBK');//使用GBK解码 console.log(text); fs.writeFileSync('utfFile.txt',iconv.encode(text, 'utf8'),'binary'); //按二进制方式写入 fs.writeFileSync('utfFile2.txt',text,'utf8'); //按UTF8写入。 ``` 这个例子首先使用fs.readFileSync方法读取GBK编码的文件,并将其保存为二进制的Buffer。然后使用iconv.decode方法将Buffer解码为GBK编码的文本。接下来,使用fs.writeFileSync方法将解码后的文本按照UTF-8编码保存为二进制文件utfFile.txt,以及按照UTF-8编码保存为UTF-8文本文件utfFile2.txt。 需要注意的是,Unicode标准允许在UTF-8中使用BOM(字节顺序标记),但一般不建议使用它。在使用Node.js处理UTF-8编码时,通常不需要使用BOM。 <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Node.js环境中使用GBK编码](https://blog.csdn.net/violentbomb/article/details/52919206)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [gulp-bom:将UTF-8 BOM添加到文件](https://download.csdn.net/download/weixin_42134338/19080088)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值