这学期选了linux高级编程这门课,马上要期末考试了,最近这几天在认真的复习,所以就把所学的知识做一个简单的总结,不然总觉得一遍过后什么也留不住。
一. Linux的文件结构
我相信大多数人都使用过Windows操作系统,它最顶级的文件结构是多个并列的树状结构,将物理磁盘分为C、D、E、F等,如下图:
Linux与Windows有很大的不同,它是一个单列的树状结构,只有一个根目录,不同的目录都挂在同一个根目录下,如图:
这个是两者最直观的区别。
二. Linux文件系统模型
学过操作系统的都知道文件是存在物理磁盘上的,不是存在内存中。操作系统对物理磁盘的访问是通过设备驱动程序来实现的。一般来说,设备驱动的访问方式分为两种:
直接调用设备驱动本身的接口,来访问物理磁盘;
通过虚拟文件系统(Vitural File System,VFS)提供的API来供上层应用访问设备驱动。
如图所示:
由于方法一是不稳定的,现在的大部分操作系统都采用了方法二的方式,只有特殊情况下才使用方法一的方式。
三. VFS提供的API
上面提到了VFS的概念,由图可以看出他就是一个提供各种访问磁盘操作的接口系统,也就是系统调用接口。如文件的创建(creat)、读(read)、写(write)等操作,像C语言的标准库函数fopen、fread,fclose等操作都是用系统调用来实现的。
在Linux中文件被分为七种类型,如下:
d : 目录文件
l : 符号链接(指向另一个文件)
b : 块设备文件
c : 字符设备文件
p : 命名管道文件
- : 普通文件
下面看下对于普通文件和目录文件所提供的接口:
普通文件:
1.对文件的创建、读、写、关闭操作。
(1)打开源文件
int open(const char *pathname, int flags);
(2)创建/重写目标文件
int creat(const char *pathname, mode_t mode);
(3)读取源文件数据
int read(int fd, void *buf, size_t count);
(4)写目的文件
int write(int fd, void *buf, size_t count);
(5)关闭源/目的文件
int close(int fd);
(6)删除文件
int unlink(const char *pathname);
int remove(const char *pathname);
可以看出对于VFS来说,文件的读写关闭都是通过文件描述符来操作的,而在C语言标准库函数中的文件操作都是通过流指针来操作的,然而文件描述符只适用于Linux和UNIX系统,所以为了程序方便移植,最好在编程中使用C语言标准库函数。
2.对文件的属性的操作。
(1)获取文件属性
int stat(const char *pathname, struct stat *buf);
(2)修改文件的权限
int chmod(const char *pathname, mode_t mode); //使用文件名
int fchmod(int fildes, mode_t mode); //使用文件描述符
目录文件:
(1)创建目录
int mkdir(const char *pathname, mode_t mode);
(2)打开目录
DIR *opendir(const char *name);
(3)读取目录项
struct dirent *readdir(DIR *dir);
(4)关闭目录
int closedir(DIR *dir);
(5)删除目录
int rmdir(const char *pathname);
int remove(const char *pathname);
上面是对普通文件和目录文件的几个常用API的介绍。
四. 文件的权限
从上面的接口函数传参可以看出,不论是创建普通文件还是目录文件,都用到一个参数st_mode mode,顾名思义就知道它指的是文件的权限。
在Linux命令行中运行ls -l
命令会出现例如:-rwxrwxrwx
的字段,它指的就是文件的权限。
- 权限被分为三组,分别是:属主权限,同组用户权限,其他用户权限。
- r代表可读权限,w代表可写权限,x代表可执行权限。
- 对于读写执行权限,他们又分别对应一个值:r = 4, w = 2, x = 1。
如下代码:
int fd = open("list.txt", O_CREAT|O_WRONLY), 0644);
上面的代码可以看到对list.txt文件的权限设置的是0644:
表示属主的权限值为6,属主具有读写权限;
同组用户和其他用户的权限值为4,具有可读权限。
其实也就是对于不同类型的用户分别执行加分操作,将然后进行或运算就是文件的权限值。