Linux Programming Prerequisite
File System
1. What is File and File System?
文件:可以写入或读取或两者兼有的对象。文件具有某些属性,包括访问权限和类型。
文件系统:文件及其某些属性的集合。它为引用这些文件的文件序列号提供了名称空间。
1.1 文件系统的多种含义
- 指一种特定的文件格式。例如,我们说Linux的文件系统是Ext2,MSDOS的文件系统是FATI6,而Windows NT的文件系统是NTFS或FAT32,就是指这个意思。
- 指按特定格式进行了”格式化”的一块存储介质。当我们说”安装”或”拆卸”一个文件系统时,指的就是这个意思。
- 指操作系统中(通常在内核中)用来管理文件系统以及对文件进行操作的机制及其实现,这就是本章的主要话题
1.2 文件类型与结构
文件类型
- 普通文件(regular file)
- 字符型设备文件(character special file)
- 块型设备文件(block special file)
- 管道(fifo)
- 网络接口(socket)
- 符号链接(symbolic link)
- 目录(directory):该目录中的文件列表
文件结构:字节流,没有特别的内部结构
1.3 Linux中的文件系统
Virtual File system Switch (VFS)
VFS模型(会考)
虚拟;仅存在于内存中
组件:
- 超级块(super block):某一个磁盘的某一个分区的文件系统的信息
- 记录文件系统类型
- 记录文件系统的参数
- i-node 对象(i-node object):index
- 记录的是真正的文件,文件存储在磁盘上时是按照索引号访问文件的
- 文件对象(file object)
- 记录的是文件描述符,索引号
- 不对应真正的文件,文件open后会创建出文件对象。
- 文件没有close,则内核中的文件对象就没有释放
- fd 是文件对象数组的下标
- 目录对象(dentry object)
Ext2 File System(不考)
1.4 硬链接和符号链接
Hard link
- 不同的文件名对应同一个inode
- 不能跨越文件系统
- 对应系统调用link
Symbolic link
- 存储被链接文件的文件名(而不是inode)实现链接
- 可跨越文件系统
- 对应系统调用symlink
为了显示文件的可访问权限,我们在使用 ls 命令的时候同时使用 -l 参数
2. 系统调用和库函数
都以C函数的形式出现
系统调用:Linux内核的对外接口; 用户程序和内核之间唯一的接口; 提供最小接口
库函数:依赖于系统调用; 提供较复杂功能
- 例:标准I/O库
2.1 无缓冲 I/O 和缓冲 I/O
Unbuffered I/O
- read/write -> System calls
- File descriptor
- Not in ANSI C, but in POSIX.1 and XPG3
Buffered I/O
- 在标准I/O库实现
- 处理很多细节, 如缓存分配, 以优化长度执行I/O等
- Stream -> a pointer to FILE
2.2 Basic I/O System Calls
文件描述符
标准I/O
open/creat, close, read, write, lseek
dup/dup2
fcntl
ioctl
文件描述符
File descriptor
- 一个小的非负整数:
int fd;
- (在
<unistd.h>
中)- STDIN_FILENO(0)
- STDOUT_FILENO(1)
- STDERR_FILENO(2)
文件操作的一般步骤:open - read/write - [lseek] - close
1 |
|
open/creat 函数
- 打开和建立一个文件或设备
- C语言不能够重载,为什么会有2个open?并不是通过重载实现的,两个open是以一个函数的形式提供的,C语言提供了变长参数的函数机制(
...
)。
1 |
|
参数 “flags”
“flags”:文件访问方式
O_RDONLY
,O_WRONLY
或O_RDWR
中的一个请求分别按以下方式对文件进行只读,只写或读/写操作,这些操作按零或多个进行按位或运算(全部在/usr/include/fcntl.h
中定义 )
O_APPEND
:以附加模式打开文件O_TRUNC
:如果文件已经存在并且是常规文件,并且打开方式允许写入,则会将其长度截断为0。O_CREAT
:如果文件不存在,将创建它。O_EXCL
:与O_CREAT一起使用时,如果文件已存在,则为错误,打开失败。
“creat”函数:相当于以等于O_CREAT | O_WRONLY | O_TRUNC
的标志打开
参数 “mode”
mode:指定在创建新文件的情况下使用的权限
需要多个权限的话,也是按位或。S_IRUSR|S_IWUSR
就表示rw-
。
umask:一种文件保护机制
新文件的初始访问方式:mode和~umask
close 函数
fcntl 函数
Manipulate a file descriptor
1 |
|
The operation is determined by”cmd”.
The value of”cmd”
F_DUPFD
:Duplicate a file descriptorF_GETFD/F_SETFD
:Get/set the file descriptor’s close-on exec flag- 执行时是否关闭,文件描述符能否从父进程传递到子进程。
F_GETFL/F_SETFL
:Get/set the file descriptor’s flagsF_GETOWN/F_SETOWN
:Manage I/O availability signalsF_GETLK/F_SETLK/F_SETLKW
:Get/set the file lock
Example:dup/dup2 and fcntl
1 |
|
1 |
|
- pid保存进程id(可以理解为int类型,linux下做了类型的重定义)
if(fd == -1)
:异常处理(文件打开失败)fcntl(fd, F_SETFD, 1);
这里将close-on-exec flag设置为true,所以调用execl的时候,fd会关闭。fork()
:Linux下很特别的系统调用,是用来创建进程的;复制一份父进程,作为父进程的子进程。(注意:被启动的子进程,就从fork()之后继续执行;子进程并不重复执行,某种程度上子进程和父进程是完全一样的;只有fork()系统调用的返回值不一样)- 父进程fork()函数的返回值就是子进程的pid,而子进程fork()函数的返回值是0。
- 子进程是复制了父进程,所以这里子进程有fd这个文件描述符。
- exec系列函数的使用
- 用另外一个程序代替当前进程,不会新开进程(用当前进程执行新的程序)
- 启动一段新的程序,将新程序的内存覆盖掉当前进程的内存。
- 如果没有fork就执行execl,则当前shell的进程没有了(呗新的程序占用了)
- 注意:
- 这里是
pid==0
,才会执行execl。所以是子进程执行了这个execl。 execl("ass", "./ass", &fd, NULL)
:传递的是fd所在地址,这里是int类型的地址,而execl函数要求的传输类型是char类型的地址,所以这里是类型转换。(但是这里的fd的值不能太大,因为是按照char类型读取的,所以fd的值在128以内应该没有问题)wait(NULL)
:父进程就在这里等待,直到子进程执行完ass- 最后的执行结果:test.txt文件中只会有”ooooo”,不会有”zzzzz”
- 这里是
ioctl 函数
控制设备驱动
1 |
|
2.3 Standard I/O Library
- File stream
- Standard I/O functions
File stream
流和”FILE”结构
FILE * fp;
- 预定义指针:
stdin, stdout, stderr
(封装了012号文件描述符)
缓冲I/O
- 三类缓冲
- 全缓冲
- 行缓冲
- 无缓冲
setbuf/setvbuf
函数
Stream Buffering Operations
Three types of buffering
- block buffered (fully buffered)
- line buffered
- unbuffered
setbuf, setvbuf
functions
1 |
|
type:_IOFBF
(满缓冲)_IOLBF
(行缓冲) _IONBF
(无缓冲)
Standard I/O functions
Stream open/close
Stream read/write
- 每次一个字符的I/O
- 每次一行的I/O
- 直接I/O(二进制I/O)
- 格式化I/O
Stream reposition
Stream flush
Stream open/close
Open a stream
1 |
|
Parameter”mode”
"r"
:Open text file for reading."w"
:Truncate file to zero length or create text file for writing."a"
:Open for appending(追加)."r+"
:Open for reading and writing."w+"
:Open for reading and writing. The file is created if it does not exist, otherwise it is truncated."a+"
:Open for reading and appending. The file is created if does not exist.
Close a stream
1 |
|
Input of a character
1 |
|
Three functions:ferror, feof, clearerr
ungetc
function:push a character back to a stream
Output of a Character
1 |
|
Input of a Line of String
1 |
|
fgets
:最多从流中读 size-1 字节并存储到 s 指向的缓冲区,读到 EOF或新行结束,“\0” 会存储到缓冲区结尾