Node.js 中 fs.stat 或 fs.statSync 方法可以获取文件信息,例如:
const fs = require('fs')
const stat = fs.statSync('./a.txt')
console.log(stat)
会返回一个 fs.Stats 对象,打印出来的效果如下:
Stats {
dev: 16777221,
mode: 33188,
nlink: 1,
uid: 501,
gid: 20,
rdev: 0,
blksize: 4096,
ino: 16908736,
size: 3860,
blocks: 8,
atimeMs: 1618116564133.5427,
mtimeMs: 1618116561126.6218,
ctimeMs: 1618116561126.6218,
birthtimeMs: 1618116561110.9902,
atime: 2021-04-11T04:49:24.134Z,
mtime: 2021-04-11T04:49:21.127Z,
ctime: 2021-04-11T04:49:21.127Z,
birthtime: 2021-04-11T04:49:21.111Z
}
异步的 fs.stat 方法接收 3 个参数:
- path
<string> | <Buffer> | <URL> - options
<Object>- bigint
<boolean>返回的 fs.Stats 对象中的数值是否为 bigint 型。 默认值是 false。
- bigint
- callback
<Function>- err
<Error> - stats
<fs.Stats>
- err
fs.Stats 对象
调用 fs.stat 或 fs.statSync 方法返回的 fs.Stats 对象上,有很多实用的属性和方法,例如可以通过 stat.isDirectory() 判断是否是文件夹,以及通过 stat.size 属性获取文件大小,接下来就详细介绍 fs.Stats 对象中的属性和方法:
isBlockDevice
- 语法:
stats.isBlockDevice() - 返回:
<boolean> - 描述:如果描述了一个块设备,则返回 true
isCharacterDevice
- 语法:
stats.isCharacterDevice() - 返回:
<boolean> - 描述:如果描述了一个字符设备,则返回 true
isDirectory
- 语法:
stats.isDirectory() - 返回:
<boolean> - 描述:如果描述一个文件系统目录,则返回 true
isFIFO
- 语法:
stats.isFIFO() - 返回:
- 描述:如果描述了一个先进先出管道,则返回 true
isFile
- 语法:
stats.isFile() - 返回:
<boolean> - 描述:如果描述了一个正常的文件,则返回 true。
isSocket
- 语法:
stats.isSocket() - 返回:
<boolean> - 描述:如果描述一个 socket,则返回 true
isSymbolicLink
- 语法:
stats.isSymbolicLink() - 返回:
<boolean> - 描述:如果描述一个符号链接,则返回 true
- 备注:这个方法只有使用
fs.lstat()时才有效
dev
- 语法:
stats.dev - 返回:
<number>|<bigint> - 描述:包含文件的设备的数字描述符
ino
- 语法:
stats.ino - 返回:
<number>|<bigint> - 描述:文件系统为文件特定的 Inode 数字
mode
- 语法:
stats.mode - 返回:
<number>|<bigint> - 描述:一个位字段描述文件类型和模式
nlink
- 语法:
stats.nlink - 返回:
<number> | <bigint> - 描述:文件存在的硬链接数
uid
- 语法:
stats.uid - 返回:
<number>|<bigint> - 描述:拥有文件的数字用户标识符
gid
- 语法:
stats.gid - 返回:
<number> | <bigint> - 描述:拥有文件的数字组标识符
rdev
- 语法:
stats.rdev - 返回:
<number>|<bigint> - 描述:如果文件被当做”特殊的”的数字设备标识符
size
- 语法:
stats.size - 返回:
<number>|<bigint> - 描述:文件有多少个字节
blksize
- 语法:
stats.blksize - 返回:
<number>|<bigint> - 描述:文件系统用于i/o操作的块的大小
blocks
- 语法:
stats.blocks - 返回:
<number>|<bigint> - 描述:为文件分配的块数
atimeMs
- 语法:
stats.atimeMs - 返回:
<number>|<bigint> - 描述:最近一次访问文件的时间戳(以 POSIX Epoch 以来的毫秒数计算)
ctimeMs
- 语法:
stats.ctimeMs - 返回:
<number>|<bigint> - 描述:最近一次文件状态的修改的时间戳(以 POSIX Epoch 以来的毫秒数计算)
birthtimeMs
- 语法:
stats.birthtimeMs - 返回:
<number>|<bigint> - 描述:文件创建时间的时间戳(以 POSIX Epoch 以来的毫秒数计算)
atime
- 语法:
stats.atime - 返回:
<Date> - 描述:文件最近一次被访问的时间戳
mtime
- 语法:
stats.mtime - 返回:
<Date> - 描述:文件最近一次修改的时间戳
ctime
- 语法:
stats.ctime - 返回:
<Date> - 描述:文件最近一次状态变动的时间戳
birthtime
- 语法:
stats.birthtime - 返回:
<Date> - 描述:文件创建的时间戳
fs.State 对象中的时间值
state 对象中的时间有以下语义:
-
atime:Access Time,表示文件最近被访问的时间被
mknod(2)、utimes(2)、和read(2)系统调用时改变 -
mtime:Modified Time,表示文件最近被修改的时间被
mknod(2)、utimes(2)、和write(2)系统调用时改变 -
ctime:Change Time,表示文件 inode 数据被修改的时间被
chmod(2)、chown(2)、link(2)、mknod(2)、rename(2)、unlink(2)、utimes(2)、read(2)和write(2)系统调用时改变 -
birthtime:Birth Time,表示文件的创建时间被
utimes(2)系统调用时改变
一定要注意,ctime 并非表示创建时间,而是修改时间,对文件进行任何修改都会影响到 ctime,例如用 chmod 改文件的权限只影响 ctime 但是不会影响 mtime,也就是说只要 mtime 发生变化,ctime一定会变但反之则不然。
atime、mtime、ctime 和 birthtime 都是 Date 对象,代表各种各样的时间,除了上面的日期类型之外,还有与其对应的保存响应的毫秒数的数字:
- atimeMs
- mtimeMs
- ctimeMs
- birthtimeMs
这个数字可能是 number 类型,也可能是 bigint 类型,如果在 options 中的 bigint 为 true,则数值会是bigint。另外需要注意,Date和数字值没有关联,当分配一个新的数字值或者改变 Date 值时,都不影响其他值。
fs.stat 方法的变体
fs.stat 方法有下面两个变体:
fs.lstat()fs.fstat()
lstat 与 stat 基本相同,区别在于:如果 path 是链接,lstat 读取的是链接本身,而不是它所链接到的文件。stat 和 lstat接收的第一个参数是一个文件路径字符串,但 fstat 就不太一样了,它接收的是一个文件描述符,例如:
const fs = require('fs')
const fd = fs.openSync('./a.txt')
console.log(fd)
const stat = fs.fstatSync(fd)
console.log(stat)
文件描述符(FD:file descriptors),是指当某个程序打开文件时,内核返回的一个正整数,程序为了处理该文件必须引用此描述符,用以标明每一个被进程所打开的文件和 socket。