文件描述符
fcntl
函数中F_GETFD/F_SETFD
表示获取或设置文件描述符属性(包括FD_CLOEXEC等);F_GETFL/F_SETFL
表示获取或设置文件状态(文件表项中的文件状态标志,包括只读、只写、读写、异步等等)。
注意,当多个进程打开同一个文件时,共享的是V节点信息。
文件的访问权限
粘着位和s权限位
与进程相关联的ID有6个或6个以上,例举如下重要的几个:
ID说明 | 作用 |
---|---|
实际用户ID 实际组ID | 实际是谁在操作进程 |
有效用户ID 有效组ID 附属组ID | 用于进程在执行过程中文件访问权限检查(和文件的所属id比较) |
保存的设置用户ID 保存的设置组ID | 在执行一个程序时可用来设置有效ID(在文件的特定权限位被设置时使用) |
当执行一个程序文件时,进程的有效用户/组ID通常就是实际用户/组ID。但是可以通过设置文件的权限位,使得执行此文件时,进程的有效用户ID设置为文件所有者的用户ID。例如,当程序文件的所有者是超级用户时,设置文件的该权限位后,当程序文件被一个进程执行时,该进程具有超级用户的权限。
该权限位也称为s权限位(包括S_ISUID(4000) 和 S_ISGID(2000))。一般只对可执行程序文件设置该权限位。
粘着位
,如果对一个目录设置了粘着位,只有对该目录有写权限的用户并且满足以下条件,才能删除目录下的文件:
- 拥有此文件
- 拥有此目录
- 是超级用户
使用chmod +t
的方式可以设置目录的粘着位(一般只针对目录设置该权限位)。
跳过缓存直接落盘
传统的UNIX系统设有缓冲区高速缓存或页高速缓存,大多数磁盘IO都是通过缓冲区进行的,当写入文件时,内核会将数据先放到缓存区缓存中,通过延时写的方式落盘。
sync函数
主动将缓冲区的缓存数据刷到磁盘中,但是它不等待实际写磁盘结束就返回。
fsync函数
只针对特定的文件起作用,并且它会等待数据实际写磁盘结束再返回。
在fcntl函数
有一个值为O_SYNC的文件状态(可以跳过缓存,一般数据库程序就会用到),使得每次write文件时,都需要等待数据实际写到磁盘上才返回(未设置该状态的情况下write采用的是延时写策略)。
IO效率
ssize_t read(int fd, void *buf, size_t count);
如何选取一个有效的count值,使得read的效率最大化。通过测试不同的数据,发现在磁盘块大小为4096byte的系统上,count的值为4096或大于4096时IO的效率最大。
大多数系统上为了改善性能都采用了某种预读
的技术。当检测到正在顺序读取数据时,系统会试图读入比应用所要求的更多数据,并假想应用很快就能应用到这些数据。
文件空洞
当文件设置的偏移量超过文件的大小,并写入一些数据后,就会造成文件空洞(文件空洞要结合文件在磁盘上存放在不连续的块中来理解)。
对于空洞处,使用read函数读出来的字节为0。通过 ls -l
命令看到的文件大小是包含空洞的,通过du -s
命令或 wc -c
可以获取文件实际的字节数 。
文件的时间(Unix)
字段 | 说明 | ls命令 | 例子 |
---|---|---|---|
st_atim | 文件数据的最后访问时间 | -u | read |
st_mtim | 文件数据的最后修改时间 | 默认 | write |
st_ctim | i节点状态的最后修改时间 | -c | chmod、chown |
IO标准库中的流和缓冲
当一个文件流被创建时(fopen),它没有被定向(流的定向决定读、写的字符是单字节还是多字节
),此时使用单字节IO函数,则流被定向为单字节流;使用多字节函数,流会被定向为多字节流。
标准IO提供了以下三种类型的缓冲:
(1)全缓冲:只有填满IO缓冲区后才会进行实际的IO操作。
(2)行缓冲:在输入输出中遇到换行符时,会进行实际的IO操作(缓冲区满时也会做IO操作)。
(3)无缓冲:没有缓冲。
重要的文件
文件路径 | 文件作用 |
---|---|
/etc/passwd | 账户信息(用户数据库) |
/etc/shadow | 账户密码(经过加密处理) |
/etc/group | 账户所属组文件(组数据库) |
/etc/services | 记录网络服务器数据文件 |
/etc/protocols | 协议信息 |
/etc/networks | 网络信息 |
/etc/resolv.conf | 域名服务器地址配置文件 |
/etc/hosts | 静态主机文件(本地域名数据库) |
/etc/services | 服务名称到端口号得映射关系文件 |