Linux应用程序设计
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

第3章

应用文件I/O

3.1 Linux文件结构

1.文件

Linux环境中的文件具有特别重要的意义,因为它们为操作系统服务和设备提供了一个简单而统一的接口。

大多数Linux资源都能以文件的方式来访问,在Linux系统中有许多种不同的文件,常见的文件类型包括:

(1)普通文件,也称为磁盘文件,被定义为能够进行随机存取的数据存储单元。它们是面向字节的,意思是从其中读出或者写入的基本单位是单个字节,单个字节也与单个字符相对应。当然,能够经常读出或者写入多个字节,但基本的单位仍然是单个字符或字节。

(2)管道文件,是一个从一端接收数据并把数据传向另一端的数据通道,一端执行写入操作,另一端执行读出操作,管道文件将在6.2节中讨论。

设备对操作系统而言也可以看做是文件,通常程序完全可以像使用文件那样使用磁盘文件、串口、打印机和其他设备。还有一些抽象的对象也可以看做是文件,如后面将讲到的网络连接socket套接字。大多数情况下,只需要使用5个基本函数:open、close、read、write和lseek。

(3)目录也是一种文件,但它是一种特殊类型的文件。在Linux系统中,即使是超级用户可能也不再被允许直接对目录进行操作。正常情况下,所有用户都必须用上层的opendir/readdir接口来读取目录,而无须了解特定系统中目录实现的具体细节。

(4)符号链接是包含了到达另一个文件的路径,它的行为和命令的别名很相似,大多数处理文件的调用都是处理链接指向的真实文件而不是链接文件本身。

(5)套接口的运行更像管道,能够让处于不同机器上的进程进行通信。

可以这么说,Linux中的任何事物都可以用一个文件代表,或者可以通过特殊的文件进行操作。当然,它们会与传统文件有一些细微的区别,但两者的基本原则是一致的。

2.文件描述符

在Linux中,对目录和设备的操作都等同于对文件的操作,因此,大大简化了系统对不同设备的处理,提高了效率。内核如何区分和引用特定的文件呢?这里用到一个重要的概念——文件描述符。对于Linux而言,所有对设备和文件的操作都是使用文件描述符来进行的。文件描述符是一个非负的整数,它是一个索引值,并指向内核中每个进程打开文件的记录表。当打开一个现存文件或创建一个新文件时,内核就向进程返回一个文件描述符;当需要读/写文件时,也要把文件描述符作为参数传递给相应的函数。

通常,一个进程启动时,都会打开3个文件:标准输入、标准输出和标准出错处理。这3个文件分别对应文件描述符为0、1和2(也就是宏STDIN_FILENO、STDOUT_FILENO和STDERR_FILENO,建议读者使用这些宏替换)。

基于描述符的I/O操作,最主要的缺点就是它不能移植到UNIX以外的系统上,尽管大多数操作系统都有输入和输出的概念,但都不是以Linux那样的方式处理I/O。如果要把一个程序移植到非Linux环境中,还是建议使用C标准定义的I/O功能。

基本描述符的第二个缺点是不直观,代码中散布着很多数字,很难阅读。虽然习惯了Linux的程序员会对这些很熟悉,但初学者可能会发现这些数字不知所云,解决的方法是使用STDIN_FILENO、STDOUT_FILENO、STDERR_FILENO宏代替数字。