详解nodejs 文本操作模块-fs模块(四)
在前文中,提到了一个概念,就是当我在读取文件时,我需要知道这个文件的数据量的大小,而在readfile的源码中,是使用的fa.fstat方法,获取到了文件的相关数据,而对于使用fstat获取到的一个对象中,所包含的属性和方法代表的具体含义,前文中并没有涉及,本篇就看下,这个state对象中,包含的数据都有哪些,并且他们分别代表的含义是什么。
方法集合
方法集合,不是说的state对象中包含的方法集合,而是说,在调用哪些api时,返回的值时一个state的实例,比如,在fstate就是其中之一。
其他方法集合包括:
- 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对象的源码
这里没有在继续给实例,是因为,在我看来,这里只是一些属性和方法的集合,如果需要,直接调用即可,所以没有什么用法的差异。
先看源码,在源码中,注释每一个属性的代表含义(该部分源自“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); };
在上文中,出现了两个属性是没有找到相关介绍的,这个时候,我就顺便查看了下nodeje的底层c++源码,找到了一段代码如下:
# if defined(__posix__) x(blksize) # else local<value> blksize = undefined(env->isolate()); # endif
其中__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实例中的属性和方法,就这些了,对于现状纯理论学习的我来说,这些属性和方法,大多数都是用不到的,不过,做个了解还是有必要的。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: Docker 安装及配置镜像加速的实现