0x01 IO基本概念
在读写文件之前需要先有一个 connection 或者 communications channel 同一个文件,这个过程通常我们称为“打开文件”。打开文件的这个 connection 标识就代表了一个文件的“文件描述符”或者“文件流”。使用该标识你可以对文件进行读写操作,当操作完成之后就可以 close 掉这个 connection,在 close 之后就不能再对文件进行读写了。
文件描述符和文件流都可以用来表示链接到一个设备(终端),管道,socket,使用该链接可以和其它进程进行通信。
但是:当你要操作一个特别的设备或者是想通过一个特别的模式去操作文件,比如说 nonblocking input 的时候,那么只能使用文件描述符。
文件流
1,文件流是 FILE 指针 2,文件流是基于低级的文件描述符IO提供了一个高级的IO接口 3,文件流针对所有文件的操作都非常相识,唯一的例外是文件流有三种缓冲方式可以选择 4,文件流相比文件描述符的优势在于它提供了更加丰富的文件操作方式 5,由于文件流是基于文件描述符实现的,所以你可以在文件流中提取出文件描述符,然后通过文件描述符执行低级的IO操作 6,同样的,你也可以采用文件描述符的方式来初始化打开一个文件,然后将它和文件流进行关联 7,推荐使用文件流来操作文件,除非你的操作必须由文件描述符才能完成 8,文件流相比文件描述符来说,可移植性更强
文件描述符
1,文件描述符是一个整数 2,文件描述符提供了一个原始的,低级的 IO 接口
文件的定位(file position)
1,file position 是文件读写的一个基础属性 2,在GUN,POSIX系统中,file position 是一个整数代表了从文件开始处读写到现在的字节数 3,当一个文件被打开时 file position 为设置到文件开始处,以后针对文件的每次读写 file position 都会增加,这就从另一方面 说明,文件读写实际上是连续的 4,通常文件都提供读写文件任意位置字符的能力,这种能力也就是我们常说的“随机读写”文件。在文件流中你可以通过 fseek 函数去改变 file position,在文件描述符中你可以通过 lseek 函数去改变 file position,如果改变一个不支持随机读写的文件的 file position 那么就会产生 ESPIPE 错误 5,对于以 append 模式打开的文件,针对该文件的写入都是从文件尾开始,而不去关心 file position,但是 file position 一样控制 了文件读的位置 6,你可能已经知道,同一个文件在同一时间可以被多个程序操作,那么为了防止互相干扰,不同的程序针对该文件应该要具有不同的文件描述符。 事实上,每一个打开的文件都具备不同的文件描述符,同样的也具有不同的 file position,这样你就可以同时操作同一个文件了在不同的程序中 7,如果你针对一个已经打开的文件描述符进行了“复制”操作,那么,这两个文件描述符指向同一个 file position,也就是说它们会相互影响
0x02 文件名称
所有IO操作前都应该通过某种方式来打开或者关联一个文件,和要操作文件进行关联的方式就是通过文件名称,不管任意类型的文件,都一定有一个名称来代表它们。
目录
1,目录之间的组织形式是有层级关系的 2,目录是一种特殊的文件,它包含其它文件,实际上是包含指向其它文件的指针,目录之间的分割使用符号:/ 3,在POSIX系统中,目录名被称为是 pathname 4,多个连续的 "/" 和一个 "/" 是等价的
文件名解析(file name resolution)
1,文件名解析的顺序是从左到右的 2,GUN 系统中是没有什么内置的文件类型的,使用文件名的后缀来表示文件类型这并不是强制的,在系统层面也没有这种规范
文件名解析错误
GUN C库中解析文件名称可能会出现以下错误,请参考官方链接:https://www.gnu.org/software/libc/manual/html_node/File-Name-Errors.html#File-Name-Errors
可移植的文件名
1,对于文件的命名要注意不能含有内嵌的字面量字符或者 null 字符等特殊字符,同时要注意文件名的长度 2,然后 GUN C 中对文件名的限制几乎没有,所以基本可以放心的用,当然 null 字符除外