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。