一、文件操作I/O
| 1 | fd = open(pathname,flags,mode) | 打开文件返回文件描述符 | flag指定打开方式及一些限制,mode指定文件访问权限 |
| 2 | numread = read(fd,buffer,maxszie) | 读文件 | 自动更新文件偏移量 |
| 3 | numwrite = write(fd,buffer,maxszie) | 写文件 | 自动更新文件偏移量 |
| 4 | status = close(fd) | 关闭文件 | 释放文件描述符资源 |
| 5 | offset_cur = lseek(fd,offset,whence) | 改变文件偏移量 | SEEK_SET、SEEK_CUR、SEEK_END |
| 6 | ioctl(fd,request,…) | ioctl系统调用来控制设备 | |
| 7 | flags = fcntl(fd,cmd,…) | 1.读取和设置打开文件的状态标记flags 2.F_DUPFD复制文件描述符 | F_GETFL和F_SETFL分别是检索和修改flags标志位的,能够更改的标志位有限制 |
| 8 | new_fd = dup(old_fd) | 复制文件描述符 | 这两个描述符共享相同的内部结构,共享所有的锁定,读写位置和各项权限或flags等等 |
| 9 | res = dup(old_fd,new_fd) | 复制文件描述符,且指定新的文件描述符 | 如果由new_fd指定的文件描述符之前已经打开,那么dup2回将其关闭。关闭old_fd时dup2回忽略关闭出现的任何异常,更为安全的做法是在dup2之前检查new_fd是否打开,若打开,就close关闭。 |
| 10 | pwrite(fd,buf,count,offset) | 与write类似,只在offset处进行I/O操作 | pread和pwrite不会改变当前文件的偏移量。 |
| 11 | pread(fd,buf,count,offset) | 与read类似 | 只在offset处进行I/O操作 |
| 12 | readv(fd,iovec *iov,cnt) preadv(fd,iovec *iov,cnt,offset) | 分散输入 | |
| 13 | writev(fd,iovec *iov,cnt) pwritev(fd,iovec *iov,cnt,offset) | 集中输出 这些系统调用一次性即可传输多个缓冲区的数据,原子操作 | |
| 14 | truncate、ftruncate | 截断文件 | |
| 15 | fd = mkstemp(path) File* tmpfile() | 生成临时文件 | 有些程序需要创建一些临时文件,仅供程序在运行期间使用,程序终止后就删除。 |
二、open flags介绍
三、文件空洞
通过lseek系统调用,可以使得文件偏移量在文件结尾后的某个位置,在文件结尾处后面的某个位置通过write写入数据,从文件结尾到写入数据的位置中间存在一段距离,这段距离称之为文件空洞。
四、系统调用的原子性
所有系统调用都是以原子操作方式执行的,内核保证了某系统调用中所有步骤作为独立操作而一次性执行完毕,中间不会被其它线程、进程所中断。
总之注意一点:单个系统调用可以确保原子性,但是两个系统调用之间就不能确定原子性,O_CREAT和O_EXCL一次性地调用open()可以确保检查文件和创建文件的步骤属于一个单一的原子(不可中断的)操作。
五、文件描述符与打开文件
-
进程级的文件描述符表
• 控制文集描述符操作的一组标志
• 对打开文件句柄的引用 -
系统级的打开文件表:表中条目称之为打开文件句柄,文件句柄中存储了与一个打开文件相关的全部信息
• 进程对文件的读写偏移量
• 打开文件时所用的状态标志
• 文件访问模式
• 与信号驱动I/O有关的设置
• 对该文件i-node对应的引用 -
文件系统索引节点表:i-node表存储文件的元信息
• 文件字节数
• 文件拥有者User ID、Group ID
• 文件rwx权限
• 文件的3个时间戳:ctime(inode上一次变动时间)、mtime(文件内容上一次变动时间)、atime(文件上一次打开时间)
• 链接数
• 文件数据block位置
可以使用stat命令查看某个文件的 inode信息
总结:
- 两个不同的文件描述符,若指向同一打开的文件句柄,将共享同一文件偏移量。如果通过其中之一的fd修改文件偏移量,那么另外一个文件描述符也会察觉这个辩护
- 文件描述符标志位进程和文件描述符私有。