4. Apue文件系统、文件类型、访问权限和目录相关函数

1、linux文件系统

windows使用NTFS,而linux使用ext2/ext3

1)ext2文件系统

一个磁盘分成一个或多个分区,每个分区包含一个文件系统
如下图所示是一个磁盘分区格式化成ext2文件系统后的存储布局
在这里插入图片描述
从布局可以看出,ext2对物理磁盘进行了分区,而每个扇区(每个区是512字节)又划分成了一个一个的组,每个组又再细分成一堆东西。

2)block

一个区是512字节,故2个区就是1kb,而设计block的时候一般使用8个区连成一个block,于是一个block就是4kb
其他的名词概念:link


2、函数stat、fstat、lstat

原型:
在这里插入图片描述
stat函数:返回与此命名文件有关的信息结构,使用该函数最多的地方ls -l,可以获得有关一个文件的所有信息
fstat函数:获得已在描述符fd上打开文件的有关信息
lstat函数:类似于stat。但当命令文件是一个符号链接时,lstat返回该符号链接的有关信息,而不是由该符号链接引用的文件的信息
这三个函数共同的一个参数,buf是一个指针,指向一个结构体用来保存返回的文件信息
在这里插入图片描述


3、文件类型

1。普通文件:这种文件包含了某种形式的数据,对普通文件内容的解释由处理该文件的应用程序进行
2。目录文件:它包含了其他文件的名字以及指向与这些文件有关信息的指针只有内核可以直接写目录文件
3。块特殊文件:它提供对设备(如磁盘)带缓冲的访问,每次访问以固定长度单位进行
4。字符特殊文件:它提供对设备(如磁盘)不带缓冲的访问,每次访问长度可变
5。FIFO:它用于进程间通信,也称为管道(pipe)
6。套接字:它用于进程间的网络通信或者一台宿主机上进程间的非网络通信
7。符号链接:它指向另一个文件
UNIX系统的文件类型主要包括上面的种,这些文件类型信息包含在stat结构体的st_mode成员
在这里插入图片描述
使用示例:
在这里插入图片描述


4、设置用户ID和设置组ID

实际用户ID和实际用户组ID:标识我们是谁。如我以dzh登录linux,那在linux运行的所有命令的实际用户ID和实际用户组ID都是dzh
有效用户ID和有效用户组ID决定了文件访问权限


5、文件访问权限

st_mode的值还包含了对文件的访问权限位
每个文件有9个访问权限位,可以将它们分成3类
在这里插入图片描述
这里的用户指的是文件所有者chmod命令用来修改这9个权限位u表示用户(所有者)g表示组o表示其他

一些规则:
1。用名字打开任一类型的文件时,对该名字中包含的每一个目录,都应具有执行权限
2。对一个文件的读或写权限决定了我们能否打开现有文件进行读或写操作
3。为了在open函数中对一个文件指定O_TRUNC标志,必须对该文件具有写权限标志
4。为了在一个目录中创建一个新文件,必须对该目录具有写权限和执行权限
5。为了在一个目录中删除一个文件,必须对包含该文件的目录具有写权限和执行权限

UNIX下可以使用ls -l来看到文件的权限,可以得到类似这样一共10位的格式:-rwxr-xr-x
在这里插入图片描述
在这里插入图片描述
从上面的可以看出,
① 他们都是普通文件,文件的所有者是dzh用户,而dzh用户属于dzh组,文件只有1个硬连接,长度是xxx个字节,后面列出了修改时间
② 所有者dzh对文件hello具有读写权限,dzh组的成员对hello有读和写的权限,而其他的用户对这个文件只有读权限。


6、函数access和faccessat

原型:
在这里插入图片描述
在这里插入图片描述
当用open打开一个文件,内核以进程的有效用户ID和有效组ID为基础执行其访问权限测试
而有时,我们希望以实际用户ID和实际组ID进行访问权限测试,这时候就需要用到这两个函数
参数mode:
F_OK:判断文件是否存在
若文件不存在,则是下面常量的按位或
R_OK:判断文件是否可读
W_OK:判断文件是否可写
X_OK:判断文件是否可执行

函数用于确定文件或文件夹的访问权限,如果指定的存取方式有效,则函数返回0,否则返回-1
在这里插入图片描述

#include <stdio.h>
#include <unistd.h>
 
int main(int argc, char *argv[]) {
	if (0 == access (argv[1], F_OK))
		printf ("文件存在\n");
	if (0 == access (argv[1], R_OK))
		printf ("文件可读\n");
	if (0 == access (argv[1], W_OK))
		printf ("文件可写\n");
	if (0 == access (argv[1], X_OK))
		printf ("文件可执行\n");
	return 0;
}


7、函数umask

原型:
在这里插入图片描述
功能:它用来设置创建文件时需要屏蔽的权限,并返回之前的值
参数mask是由中的9个常量中的若干个按位或得到的
若想任何用户都能读文件,则应将umask设置为0


8、函数chmod、fchmod和fchmodat

原型:
在这里插入图片描述
chmod:在指定的文件上进行操作
fchmod:对已打开的文件进行操作
为了改变一个文件的权限位,进程的有效用户ID必须等于文件的所有者ID,或者该进程必须具有超级用户权限
参数mode:是那些个常量的按位或

9、黏着位

任一用户(用户、组、其他)对这两个目录的权限通常都是读、写、执行。但是用户不应能删除或重命名属于其他人的文件。于是在这两个目录的文件模式中都设置了黏着位。

10、chown、fchown和lchown函数

原型:
在这里插入图片描述
参数1:文件路径或文件描述符
参数2:用户ID
参数3:组ID
功能:用于更改文件的用户ID和组ID
① 在符号链接的情况下,lchown更改符号链接本身的所有者,而不是该符号链接所指向的文件
② 若两个参数owner或group中的任意一个是-1,则对应的ID不变

11、文件长度

stat结构成员st_size表示以字节为单位的文件的长度。该字段只对普通文件、目录文件和链接符号有意义。

普通文件:其长度可以是0,在开始读这种文件时,将得到文件结束(EOF)指示
目录文件:其长度通常是一个数(如16或512)的整倍数
符号链接:其长度是在文件名中的实际字节数。由于符号链接文件长度总是由st_size指示,所以它并不包含名字结尾的null字节

12、文件空洞

产生原因:空洞是由于所设置的偏移量超过文件尾端,并写入了某些数据造成的
对于没有写过的字节位置,read函数读到的字节是0
在这里插入图片描述
说明:位于文件中但没有被写过的字节都被设为0文件空洞不占用磁盘空间,但被计算在文件大小之内
在这里插入图片描述
显然,可执行文件test中有很多空洞
另外,也可以利用wc命令计算文件中的字符数(字节)
在这里插入图片描述

13、文件截断

有时需要在文件尾端截去一些数据以缩短文件。
特例:在打开文件时利用O_TRUNC将文件的长度截断为0
否则需要利用下面的两个函数
在这里插入图片描述
参数1:文件路径或文件描述符
参数2:文件长度(截断后)
功能:
将一个现有文件的长度截断为length
若原来文件长度大于length,则超过length以外的数据就不能再访问
若原来文件长度小于length,则文件的长度将增加,中间的数据将读作0(空洞)

14、函数link、linkat、unlink、unlinkat

1)link和linkat:

原型:
在这里插入图片描述
在这里插入图片描述
功能:创建一个指向现有文件的链接(硬链接),即创建一个新目录项newpath,它引用现有文件oldpath。如果newpath已存在,则返回出错
创建新目录项和增加链接计数(inode结构体引用计数加1)应当是一个原子操作,要么全部成功,要么全部失败
下面的例子调用link函数为文件hello创建了一个hello.link的硬链接,硬链接为2。并且创建硬链接前后,磁盘的可用空间大小没有变化
在这里插入图片描述

2)unlink和unlinkat:

原型:
在这里插入图片描述
在这里插入图片描述
功能:
这两个函数删除目录项,并将由pathname所引文件的链接计数(inode引用计数)减1。这两步也是一个原子操作
如果对该文件还有其他链接,则仍可通过其他链接访问该文件的数据。
只有当链接计数达到0时,该文件的内容才可删除:关闭一个文件时,内核首先检查打开该文件的进程个数,如果这个计数为0,内核再去检查其链接计数,如果也为0,则删除该文件的内容。

15、rename和renameat函数

原型:
在这里插入图片描述
在这里插入图片描述
1。如果oldpath是一个文件而不是目录,那么为该文件或符号链接重命名
2。如果oldpath是一个目录,那么为该目录重命名
3。如果oldpath或newpath引用符号链接,则处理的是符号链接本身而不是它所引用的文件
4。不能对.和…重命名
5。如果oldpath和newpath引用同一文件,则函数不做任何更改而返回

16、符号链接的创建和读取

符号链接是对一个文件的间接指针,而硬链接直接指向文件的i节点
引入符号链接的原因是为了避开硬链接的一些限制

  • 硬链接通常要求链接和文件位于同一文件系统中
  • 只有超级用户才能创建指向目录的硬链接

对符号链接以及它指向的何种对象并无任何文件系统限制,任何用户都可以创建指向目录的符号链接。符号链接一般用于将一个文件或整个目录结构移到系统中另一个位置

原型:
在这里插入图片描述
在这里插入图片描述
功能:
创建符号链接创建了一个指向oldpath的新目录项newpath
创建此符号链接时,并不要求oldpath和newpath位于同一文件系统中

17、文件的时间

每个文件维护3个时间字段
在这里插入图片描述
修改时间:文件内容最后一次被修改的时间
状态更改时间:文件的i节点最后一次被修改的时间,i节点中的所有信息都是与文件的实际内容分开存放的,i节点一般在下面的情况下会被更改而不更改文件内容

  • 更改文件访问权限、更改用户ID、更改链接数等

注意:系统并不维护对一个i节点的最后一次访问时间
ls命令默认按文件的修改时间先后顺序显示,-u选项按访问时间排序,-c选项按状态更改时间排序

18、mkdir和rmdir函数

目录的权限位
目录的权限位,至少要设置一个执行许可位。即 rwx 中的那个 x 位。如果不设置,就没办法使用 cd 命令进入目录,也无法读取目录下的文件内容。所以,这个位是必须的。
目录的写权限位。如果未设置写权限位(w 位),将导致无法向目录文件中写入目录项(dir_entry 结构)。比如不能使用 touch 命令创建文件。
目录的读权限位。如果未设置读权限位,将导致无法读取目录文件中的目录项。比如你不能使用 ls 命令查看目录项的具体内容。
推荐使用的目录权限位rwxrwxr-x,即 8 进制的 775。用0775表示

1)mkdir原型:

在这里插入图片描述
功能:
创建一个新的空目录。其中,.和..目录项是自动创建的。所指定的文件访问权限mode由进程的文件模式创建屏蔽字修改

2)rmdir原型:

在这里插入图片描述
功能:
删除一个空目录空目录是只包含.和..这两项的目录

19、读目录

对某个目录具有访问权限的任意用户都可以该目录,但是为了防止文件系统产生混乱,只有内核才能写目录

猜你喜欢

转载自blog.csdn.net/CSDN_dzh/article/details/85085013