文章目录
1、innode
其本质为结构体,存储文件的属性信息。如:权限、类型、大小、时间、用户(ls -l查询出来的信息都放在innode里面)、盘块位置(文件内容存储在磁盘上的位置)……innode也叫作文件属性管理结构,大多数的 inode 都存储在磁盘上。
文件名单独存储,存储文件名的地方还会有innode,这个地方叫dentry(目录项)
创建一个文件的硬链接,它们拥有着相同的innode,只是有不同的dentry
删除一个硬链接只是删除引用innode的链接,当删除所有的硬链接后,innode的引用值为0,但并不会删除磁盘上的内容,如果重建innode数据还会恢复
2、dentry
目录项,其本质依然是结构体,重要成员变量有两个{文件名,inode,…},而文件内容(data)保存在磁盘盘块中。
3、stat函数
作用:获取文件信息
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int stat(const char *path, struct stat *buf)
参数一:文件名
参数二:inode结构体指针(传出参数)
返回值:成功返回0,失败返回-1;
stat结构体内容:
struct stat
{
dev_t st_dev; /* ID of device containing file */文件使用的设备号
ino_t st_ino; /* inode number */ 索引节点号
mode_t st_mode; /* protection */ 文件对应的模式,文件,目录等
nlink_t st_nlink; /* number of hard links */ 文件的硬连接数
uid_t st_uid; /* user ID of owner */ 所有者用户识别号
gid_t st_gid; /* group ID of owner */ 组识别号
dev_t st_rdev; /* device ID (if special file) */ 设备文件的设备号
off_t st_size; /* total size, in bytes */ 以字节为单位的文件容量
blksize_t st_blksize; /* blocksize for file system I/O */ 包含该文件的磁盘块的大小
blkcnt_t st_blocks; /* number of 512B blocks allocated */ 该文件所占的磁盘块
time_t st_atime; /* time of last access */ 最后一次访问该文件的时间
time_t st_mtime; /* time of last modification */ /最后一次修改该文件的时间
time_t st_ctime; /* time of last status change */ 最后一次改变该文件状态的时间
};
例子
struct stat sbuf;
int a= stat("./a.c", &sbuf);
获取文件大小: sbuf.st_size
获取文件类型: sbuf.st_mode
获取文件权限: sbuf.st_mode
printf("文件大小 %d",sbuf.st_size);
stat结构体中的st_mode 则定义了下列数种情况:
S_IFMT 0170000 文件类型的位遮罩(掩码),可以与stat结构体中的st_mode与运算
S_IFSOCK 0140000 套接字
S_IFLNK 0120000 符号连接
S_IFREG 0100000 一般文件
S_IFBLK 0060000 区块装置
S_IFDIR 0040000 目录
S_IFCHR 0020000 字符装置
S_IFIFO 0010000 先进先出
S_ISUID 04000 文件的(set user-id on execution)位
S_ISGID 02000 文件的(set group-id on execution)位
S_ISVTX 01000 文件的sticky位
S_IRUSR(S_IREAD) 00400 文件所有者具可读取权限
S_IWUSR(S_IWRITE)00200 文件所有者具可写入权限
S_IXUSR(S_IEXEC) 00100 文件所有者具可执行权限
S_IRGRP 00040 用户组具可读取权限
S_IWGRP 00020 用户组具可写入权限
S_IXGRP 00010 用户组具可执行权限
S_IROTH 00004 其他用户具可读取权限
S_IWOTH 00002 其他用户具可写入权限
S_IXOTH 00001 其他用户具可执行权限
上述的文件类型在POSIX中定义了检查这些类型的宏定义:
S_ISLNK (st_mode) 判断是否为符号连接
S_ISREG (st_mode) 是否为一般文件
S_ISDIR (st_mode) 是否为目录
S_ISCHR (st_mode) 是否为字符装置文件
S_ISBLK (s3e) 是否为先进先出
S_ISSOCK (st_mode) 是否为socket
若一目录具有sticky位(S_ISVTX),则表示在此目录下的文件只能被该文件所有者、此目录所有者或root来删除或改名,在linux中,最典型的就是这个/tmp目录啦。
例如
struct stat sbuf;
int a= stat("./a.c", &sbuf);
if(S_ISREG(sbuf.st_mode))
{
printf("这个是一般文件");
}else if(S_ISDIR (sbuf.st_mode)){
printf("这个是一个目录");
}else if(S_ISLNK (sbuf.st_mode)){
printf("这个是一个软链接");
}
穿透符号链接:不看链接这个文件而去看链接指的内容
默认stat函数穿透符号链接
而lstat函数不会穿透符号链接
cat会穿透符号链接
ls不会穿透符号链接
4、lstat函数
将上面的stat函数改为lstat函数,其他的不变
5、access函数、chmod函数、truncate函数
- access函数:测试指定文件是否存在/拥有某种权限。
- chmod函数:修改文件访问权限。
- truncate函数:截断文件长度成指定长度。常用来拓展文件大小,代替lseek。
6、link函数
link 函数专门用来创建硬链接的,功能和 ln 命令一样。它主要做两件事:
- 创建一个目录项
- inode 结构体引用计数加 1。
这两步是一个原子操作,要么全部失败,要么全部成功。
#include <unistd.h>
int link(const char *oldpath, const char *newpath);
参数:
oldpath: 原始文件名
newpath: 新的硬链接名
7、unlink函数
删除一个名字(某些情况下删除这个名字所指向的文件)
#include<unistd.h>
int unlink(const char* pathname);
返回值:调用成功返回0,不成功返回-1.
删除时
- 如果这个名字是指向这个文件的最后一个链接,并且没有进程处于打开这个文件的状态,则删除这个文件,释放这个文件占用的空间。
- 如果这个名字是指向这个文件的最后一个链接,但有某个进程处于打开这个文件的状态,则暂时不删除这个文件,要等到打开这个文件的进程关闭这个文件的文件描述符后才删除这个文件。
- 如果这个名字指向一个符号链接,则删除这个符号链接。
- 如果这个名字指向一个socket、fifo或者一个设备,则这个socket、fifo、设备的名字被删除,当时打开这些socke、fifo、设备的进程仍然可以使用它们。
unlink的特征
清除文件时,如果文件的硬链接数到0了,没有dentry对应,但该文件仍不会马上被释放。要等到所有打开该文件的进程关闭该文件,系统才会挑时间将该文件释放掉。
unlink的用途
运行一个程序时有时需要创建一些临时文件。如果进程运行过程中突然终止了,而临时文件还没来的及删除,那么就会遗留下很多没用的临时文件,unlink提供了解决这个问题的一种方法。创建一个临时文件后一刻调用unlink删除文件。但是进程还是打开该文件的,所以该临时文件内容依旧是能被访问读和写的。但是进程终止后,该文件内容就会被删除。 ·
8、readlink
读取符号链接文件本身的内容,得到链接所指向的文件名。
ssize_t readlink(const char *path,char *buf,size_t bufsiz);成功返回实际读到的字节数,失败返回-1,设置errno为相应值。
也可以在bash上输入,比如readlink t.soft 会显示这个硬链接执行的位置
9、rename函数
重命名一个文件
int rename(const char *oldpath,const char *newpath);
成功:0,失败:-1,设置errno为相应值。
10、隐式回收
当进程结束运行时,所有该进程打开的文件会被关闭,申请的内存空间会被释放。系统的这一特性称之为隐式回收系统资源。·因此在程序中打开了fd但是没有回收,在程序退出后会进行隐式回收。但不能依赖这个特性。