第3天.文件的操作
硬件设备在Linux操作系统中通常会被映射为文件。
硬链接和软链接(符号链接 symlink)http://blog.chinaunix.net/uid-23208702-id-75180.html
用来访问设备驱动程序的底层函数,就是系统调用。
系统调用会降低计算机的执行性能,因为Linux没有一个在运行用户程序代码和执行内核代码两种情况之间来回切换的开关(内核态转到用户态,@操作系统),因此系统调用比函数调用开销要更大。
open的系统调用中的oflags参数是通过把人们要求的文件访问模式与其他可选模式按位OR操作得到的。(比如O_CREAT|O_WRONLY|O_TRUNC)
当前文件偏移量(cfo,current file offset):通常是一个非负数,表明文件开始处到文件当前位置的字节数,文件打开时,它会被初始化为0,除非用O_APPEND,但是文件打开时的读写位置通常是初始化之前的值。
对于普通文件(regular file),cfo 是一个非负整数。但对于特殊设备,cfo 有可能是负数。因此,我们不能简单地测试 lseek 的返回值是否小于 0 来判断 lseek 成功与否,而应该测试 lseek 的返回值是否等于 -1 来判断 lseek 成功与否。
lseek 仅将 cfo 保存于内核中,不会导致任何 I/O 操作。这个 cfo 将被用于之后的读写操作。
如果 offset 比文件的当前长度更大,下一个写操作就会把文件“撑大(extend)”。这就是所谓的在文件里创造“空洞(hole)”。没有被实际写入文件的所有字节由重复的 0 表示。空洞是否占用硬盘空间是由文件系统(file system)决定的。
文件描述符:当一个文件打开后,系统会分配资源来保存该文件的信息,之后对文件的操作可以直接引用该部分资源,文件修饰符可以认为是该部分资源的一个索引,在打开文件时返回,它指向内核为每一个进程所维护的该进程打开文件的记录表。很多函数需要用到这个描述符。文件描述符还能引用管道和FIFO,lseek系统调用可以改变当前文件偏移量,当如果是管道或FIFO等,就会返回-1.
文件描述符是由无符号整数表示的句柄,进程使用它来标识打开的文件,文件描述符与包括相关信息(如文件的打开模式,文件的位置类型,文件的初始类型)的文件对象相关联,这些信息被称为文件的上下文。
文件描述符对于每个进程一般是唯一的,而且不会与运行中的其他程序共享。如果open成功,它会返回一个新的文件描述符(文件修饰符永远是一个非负整数,失败就返回-1,并对全局性的errno变量进行设置以指明失败的原因)
进程获取文件描述符最常见的方法是通过本机子例程open或create获取或者通过从父进程继承。后一种方法允许子进程同样能够访问由父进程使用的文件。
对于每个进程,操作系统内核在u_block结构中维护文件描述符表,所有的文件描述符都在该表中建立索引。
creat系统调用相当于open(pathname, O_WRONLY|O_CREAT|O_TRUNC, mode);
creat的不足之处是它之一致谢方式打开所创建的文件,即如果要创建一个临时文件,并要先写该文件,则必须要调用creat、close,再调用open。?
访问权限的初始化值,定义在头文件/sys.stat.h里面定义的,能够控制各种用户对像对创建文件操作权限。
用户掩码(user mask,由shell的umask命令设定)会影响到被创建文件的反问权限。open调用里给出的模式值(即访问权限的初始化值)将在程序运行时与用户掩码的反值做AND操作。(比如用户掩码设置为“001”,open调用给出了S_IXOTH模式标志,那么文件不会被创建为其他用户拥有执行权限的情况,这是因为用户掩码中规定不允许向其他用户提供执行权限)。
open和creat调用中的标志实际山是设置权限的申请,所申请的权限是否会被设置还要取决于umask在程序运行时取的值。
umask系统变量,这是一由3个八进制问数字组成的值,各个数字都是八进制值1、2、4的AND操作结果。这三个数字分别对应着用户(user)、分组(group)、其他用户(other)的访问权限。
创建文件时,mode参数(open和creat的参数)将与umask进行比较,如果mode参数中的置位在umask中也被置位了,就会被排除在访问权限的构成之外。(比如,这样做的结果是用户可以设置自己的环境为“不准创建允许其他用户有写权限的文件,即使创建该文件的程序提出申请也不行”,这样做不会影响某个程序或用户在今后使用chmod命令或者程序中使用chmod系统调用添加其他写权限),能够方便用户保护自己的文件。
可以用unlink系统调用来删除一个文件,通过减少指定文件上的链接技术实现删除目录数据项的目的,但必须拥有这个子目录的写和执行权限。如果某个文件上的链接技术减少到零,并且没有进程打开并使用着它,这个文件就会被删除。在实际操作中,目录数据项肯定是被删除了,但文件占用空间还要等最后一个控制进程关闭他之后才会被系统回收。rm程序使用的就是这个系统调用。如果想在编程中是实现ln程序的功能(即创建文件上额外的链接表示这个文件还有其他名字),可以用link系统调用。
瞬时文件的创建技巧:先用open创建一个文件,然后对他调用unlink。这些文件只有在打开的时候才能被程序使用,当程序退出或关闭这些文件的时候它们就会被自动删除。
用symlink系统调用可以创建新的符号链接(软链接)。