文件和目录操作的系统函数(整理)

我们平时常用cp,mv,chmod,mkdir等命令,却不太清楚他们的系统调用。在《Linux C一站式学习中》的ext2文件系统中详细介绍了文件和目录操作的系统函数,理解了这些系统函数的实现原理之后,对于文件及目录操作命令也会有更深的理解,整理如下:

stat(2)函数读取文件的inode,然后把inode中的各种文件属性填入struct stat结构体传出给调用者。stat(1)命令是基于stat函数实现的。stat可以通过传入的文件路径找到其对应的inode。

还有另外两个类似stat的函数:fstat(2)函数传入一个已打开的文件描述符,传出inode信息,lstat(2)函数也是传入路径传出inode信息,但是和stat函数有一点不同,当文件是一个符号链接时,stat(2)函数传出的是它所指向的目标文件的inode,而lstat函数传出的就是符号链接文件本身的inode。lstat(2)专门用来处理符号链接。

access(2)函数检查执行当前进程的用户是否有权限访问某个文件,传入文件路径和要执行的访问操作(读/写/执行),access函数取出文件inode中的st_mode字段,比较一下访问权限,然后返回0表示允许访问,返回-1表示错误或不允许访问。

chmod(2)和fchmod(2)函数改变文件的访问权限,也就是修改inode中的st_mode字段。这两个函数的区别类似于stat/fstat。chmod(1)命令是基于chmod函数实现的。

chown(2)/fchown(2)/lchown(2)改变文件的所有者和组,也就是修改inode中的User和Group字段,只有超级用户才能正确调用这几个函数,这几个函数之间的区别类似于stat/fstat/lstat。chown(1)命令是基于chown函数实现的。

utime(2)函数改变文件的访问时间和修改时间,也就是修改inode中的atime和mtime字段touch(1)命令是基于utime函数实现的。

truncate(2)和ftruncate(2)函数把文件截断到某个长度,如果新的长度比原来的长度短,则后面的数据被截掉了,如果新的长度比原来的长度长,则后面多出来的部分用0填充,这需要修改inode中的Blocks索引项以及块位图中相应的bit。这两个函数的区别类似于stat/fstat。

link(2)函数创建硬链接,其原理是在目录的数据块中添加一条新记录,其中的inode号字段和原文件相同。symlink(2)函数创建一个符号链接,这需要创建一个新的inode,其中st_mode字段的文件类型是符号链接,原文件的路径保存在inode中或者分配一个数据块来保存。ln(1)命令是基于link和symlink函数实现的。

unlink(2)函数删除一个链接。如果是符号链接则释放这个符号链接的inode和数据块,清除inode位图和块位图中相应的位。如果是硬链接则从目录的数据块中清除一条文件名记录,如果当前文件的硬链接数已经是1了还要删除它,就同时释放它的inode和数据块,清除inode位图和块位图中相应的位,这样就真的删除文件了。unlink(1)命令和rm(1)命令是基于unlink函数实现的。

rename(2)函数改变文件名,需要修改目录数据块中的文件名记录,如果原文件名和新文件名不在一个目录下则需要从原目录数据块中清除一条记录然后添加到新目录的数据块中。mv(1)命令是基于rename函数实现的,因此在同一分区的不同目录中移动文件并不需要复制和删除文件的inode和数据块,只需要一个改名操作,即使要移动整个目录,这个目录下有很多子目录和文件也要随着一起移动,移动操作也只是对顶级目录的改名操作,很快就能完成。但是,如果在不同的分区之间移动文件就必须复制和删除inode和数据块,如果要移动整个目录,所有子目录和文件都要复制删除,这就很慢了。

readlink(2)函数读取一个符号链接所指向的目标路径,其原理是从符号链接的inode或数据块中读出保存的数据,这就是目标路径。

mkdir(2)函数创建新的目录,要做的操作是在它的父目录数据块中添加一条记录,然后分配新的inode和数据块,inode的st_mode字段的文件类型是目录,在数据块中填两个记录,分别是.和..,由于..表示父目录,因此父目录的硬链接数要加1mkdir(1)命令是基于mkdir函数实现的。

rmdir(2)函数删除一个目录,这个目录必须是空的(只包含.和..)才能删除,要做的操作是释放它的inode和数据块,清除inode位图和块位图中相应的位,清除父目录数据块中的记录,父目录的硬链接数要减1。rmdir(1)命令是基于rmdir函数实现的。

opendir(3)/readdir(3)/closedir(3)用于遍历目录数据块中的记录。opendir打开一个目录,返回一个DIR 指针代表这个目录,它是一个类似FILE 指针的句柄,closedir用于关闭这个句柄,把DIR *指针传给readdir读取目录数据块中的记录,每次返回一个指向struct dirent的指针,反复读就可以遍历所有记录,所有记录遍历完之后readdir返回NULL。

参考:http://akaedu.github.io/book/ch29s02.html#fs.datablock

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值