Node.js fs模块State对象属性详解

作者:服务小站时间:2026-10-21 18:51:27浏览:203

本文深入解析Node.js fs模块中fstat、lstat和stat方法返回的State对象。详细列举了dev、mode、nlink、rdev等核心属性的具体含义,并探讨了__POSIX__宏定义及块设备与字符设备的底层区别,帮助开发者理解文件状态信息的底层实现。

State对象概述

前文曾提及,在读取文件时需知晓数据量大小,而readFile源码中调用了fa.fstat方法以获取文件相关数据。此前未涉及通过fstat获取的对象中各属性与方法的具体含义,本文将详细解析State对象包含的数据及其代表意义。

返回State实例的方法

方法集合

此处所述的方法集合,并非指State对象内部包含的方法,而是指调用特定API时返回值为State实例的情况,例如fstat方法即属于此类。

其他相关方法包括:

  • fs.fstat
  • fs.lstat
  • fs.stat

上述方法均存在同步版本,此处不再赘述。fstat与stat主要用于查看文件信息,而lstat则用于查看目录信息,三者在调用方式上存在差异。


fs.stat(path,callback); 
//传入的参数是文件路径,和回调函数 
 
fs.lstat(path,callback); 
//传入的参数是目录的路径,和回调函数 
 
fs.fstat(fd,callback); 
//传入的参数是文件描述符,和回调函数 
//所以,该方法在readFile时,在open打开文件成功之后,才使用。 
 
callback(err,stats){ 
//回调函数的参数是相同的,第一个参数为错误对象,包含错误信息 
//第二个参数,也就是本篇文章的重点,为一个State对象的实例,包含对应文件的或者目录的相关信息 
} 

State对象源码解析

State对象源码分析

此处不再提供额外实例,因为State仅包含属性和方法的集合,直接调用即可,用法上无显著差异。

首先查看源码,源码中注释了每个属性的具体含义(部分参考自《Nodejs权威指南》)。


// Static method to set the stats properties on a Stats object. 
fs.Stats = function( 
  dev, 
  mode, 
  nlink, 
  uid, 
  gid, 
  rdev, 
  blksize, 
  ino, 
  size, 
  blocks, 
  atim_msec, 
  mtim_msec, 
  ctim_msec, 
  birthtim_msec) { 
    this.dev = dev; 
    //dev为文件或者目录所在的设备ID,只有在UNIX操作系统下该值有效 
 
    this.mode = mode; 
    //和之前在write时的mode属性相同,为文件的权限标志,数字形式 
 
    this.nlink = nlink; 
    //文件或目录的硬连接数,类似于一个文件的别名,使用fs.link创建,使用fs.unlink删除, 
    //我这里不太理解这个存在的意义,所以接下来也不会有这个相关的内容 
 
    this.uid = uid; 
    //uid为文件或者目录的所有者的用户ID,仅在UNIX操作系统有效 
 
    this.gid = gid; 
    //gid为文件或者目录所有者所在组的ID,仅在UNIX操作系统有效 
 
    this.rdev = rdev; 
    //字符设备文件或者块设备文件所在的设备ID,仅在UNIX操作系统有效 
 
    this.blksize = blksize; 
    //没有在任何地方,看到关于该属性的描述,源码中 
 
    this.ino = ino; 
    //文件或者目录的索引编号,仅在UNIX操作系统下有效 
 
    this.size = size; 
    //文件尺寸,即文件中的字节数 
 
    this.blocks = blocks; 
    //没有看到相关的介绍 
 
    this.atime = new Date(atim_msec); 
    //文件数据上次被访问的时间.会被 mknod(2), utimes(2), and read(2) 等系统调用改变。 
 
    this.mtime = new Date(mtim_msec); 
    // 文件上次被修改的时间。 会被 mknod(2), utimes(2), and write(2) 等系统调用改变 
 
    this.ctime = new Date(ctim_msec); 
    //文件状态上次改变的时间。 (inode data modification).  
    //会被 chmod(2), chown(2), link(2), mknod(2), rename(2),  
    //unlink(2), utimes(2), read(2), and write(2) 等系统调用改变。 
 
    this.birthtime = new Date(birthtim_msec); 
    // 文件被创建的时间。 会在文件被创建时生成。 在一些不提供文件birthtime的文件系统中,  
    //这个字段会被 ctime 或 1970-01-01T00:00Z (ie, unix epoch timestamp 0)来填充 
 
}; 
 
//属于一个判断各个属性的方法,其他方法,都是基于调用该方法,获取得到的返回值。 
fs.Stats.prototype._checkModeProperty = function(property) { 
  return ((this.mode & constants.S_IFMT) === property); 
}; 
 
//用于判断被查看的对象是否为一个目录,返回true,false 
fs.Stats.prototype.isDirectory = function() { 
  return this._checkModeProperty(constants.S_IFDIR); 
}; 
 
//用于判断,被查看的对象是否为一个文件,返回true,false,于isDirectory的返回值相反 
fs.Stats.prototype.isFile = function() { 
  return this._checkModeProperty(constants.S_IFREG); 
}; 
 
//用于判断被查看的文件时否为一个块设备文件(概念请看源码之后),返回true,false,只在UNIX操作系统有效 
fs.Stats.prototype.isBlockDevice = function() { 
  return this._checkModeProperty(constants.S_IFBLK); 
}; 
 
//用于判断被查看的文件,是否为一个字符设备文件,返回true,false,只在UNIX系统下有效 
//本以为其值与isBlockDevice返回值相反,但是测试了一下,都是返回的false(MAC系统,操作.js的文件), 
//可能是有些关系不,暂时不太了解 
fs.Stats.prototype.isCharacterDevice = function() { 
  return this._checkModeProperty(constants.S_IFCHR); 
}; 
 
//被查看的文件是否为一个符号链接文件,返回true,false,该方法只在lstat的回调函数中有效。 
//如果被查看的文件是符合链接文件,那么就认为改符号链接是一个目录,需要使用lstat查看相关的属性才行。 
fs.Stats.prototype.isSymbolicLink = function() { 
  return this._checkModeProperty(constants.S_IFLNK); 
}; 
 
//查看文件是否为一个FIFO文件,返回true,false,仅在UNIX系统下有效 
fs.Stats.prototype.isFIFO = function() { 
  return this._checkModeProperty(constants.S_IFIFO); 
}; 
 
//判断一个文件是否为socket文件,返回true,false,仅在UNIX系统下有效。 
//话说:有socket文件这种文件?socket文件也可以判断的? 
fs.Stats.prototype.isSocket = function() { 
  return this._checkModeProperty(constants.S_IFSOCK); 
}; 

前文提及两个属性缺乏相关介绍,为此查阅Node.js底层C++源码,找到一段相关代码如下:


# if defined(__POSIX__) 
  X(blksize) 
# else 
  Local<Value> blksize = Undefined(env->isolate()); 
# endif 

POSIX标准与__POSIX__宏

其中__POSIX__应表示是否支持POSIX标准。

POSIX的百度百科定义如下:

POSIX代表可移植操作系统接口(Portable Operating System Interface,缩写为POSIX)。POSIX标准定义了操作系统应为应用程序提供的接口标准,是IEEE为在各种UNIX操作系统上运行软件而定义的一系列API标准的总称,其正式称呼为IEEE 1003,国际标准名称为ISO/IEC 9945。

由此可见,该属性仅在UNIX系统下生效,但具体指代的值尚未明确,暂且搁置。

块设备与字符设备区别

块设备和字符设备概念(源自百度百科):

I/O设备大致分为两类:块设备和字符设备。块设备将信息存储在固定大小的块中,每个块拥有独立地址,数据块大小通常在512字节到32768字节之间。块设备的基本特征是每个块能独立于其他块进行读写,磁盘是最常见的块设备。

在大多数UNIX操作系统中,块设备仅支持以块为单位的访问方式,如磁盘等。KYLIN系统支持以字符方式访问块设备,即支持以字符为单位读写磁盘等块设备。因此,/dev目录中的块设备(如磁盘)以字符设备外观出现。字符设备与块设备的区别主要体现在KYLIN内核中的管理方式、操作方式以及内核/设备驱动接口上。

总结

State实例中的属性和方法大致如上。对于当前仅进行理论学习的情况,这些属性和方法大多用不到,但了解其含义仍有必要。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章