Linux程序设计第三章 文件操作
本篇主要是针对Linux中的文件、目录以及相关操作。主要介绍系统调用和标准I/O库。linux中,一切都是以文件的形式来表示的,包括一些硬件设备。大多数情况下,只需要使用五个基本的函数--open close read write 和ioctl。目录也是文件,它用来保存其他文件的节点号(inode)和名字。正常情况下,所有用户都必须用上层opendir/readdir接口来读取目录。文件的一些属性信息都被保存在文件的inode数据结构中,它还包含文件的长度和文件在磁盘上的存放位置。下面主要介绍下inode节点的一些信息。
linux文件系统(EXT2)通常将文件的属性、权限以及文件的数据内容存放在不同的块中,将文件的属性与权限存放在inode中,实际数据则放置在data block块中。还有一个超级块,会记录整个文件系统的整体信息,包括inode与block的总量、使用量、剩余量等。inode记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的block号码,而且每个inode的大小均为固定的128bytes(鸟哥是这么说的,但是Ubuntu系统中的Inode大小为256B)。这样就方便快速的查找出数据,我们现找到文件的inode然后知道了该文件数据所在的块,这样就能快速的读取数据
linux中比较重要的设备文件有三个--/dev/console /dev/tty /dev/null 第一个是表示系统控制台,过去会有一个指定的终端或者显示器来接收控制台消息,现在通常是虚拟控制台,比如在X视窗系统中,它是屏幕上的一个特殊的控制台窗口,就是我们说的终端。/dev/tty。如果一个进程有控制终端的话,那么特殊文件/dev/tty就是这个控制终端(键盘或者显示屏,或者键盘和窗口)的别名(逻辑设备)。
注意:虽然/dev/console设备只有一个,但是通过/dev/tty却能够访问许多不同的物理设备。
/dev/null是空设备,所有写向这个设备的输出都将被丢失。
我们用很少量的函数就可以对文件和设备进行访问和控制,这些函数被称为系统调用。操作系统的核心,即内核,是一组设备驱动程序。为了向用户提供一个统一的接口,设备驱动程序封装了所有与硬件相关的特性。硬件的特有功能可通过ioctl调用来完成。用来访问设备驱动程序的底层函数(系统调用)包括:
open:打开文件或设备。
read:从打开的文件或设备里读取数据
write:向文件或设备写入数据
close:关闭文件或设备
ioctl:把控制信息传递给设备驱动程序
下面分别介绍以下这五个系统调用函数。
1.open系统调用。创建新的文件描述符需要使用系统调用open。
- #include <fcntl.h>
- #include <sys/types.h>
这是要使用open系统调用需要用到的库,即头文件。以及函数原型,函数返回值为这个文件的文件描述符。准备打开的文件或设备的名字作为参数path传递给函数,oflags参数用来定义打开文件所采取的动作。oflags参数是通过主要文件访问模式与其他可选模式的结合来指定的。它必须指定以下所示的文件访问模式之一:O_RDONLY 以只读方式打开 O_WRONLY 以只写方式打开 O_RDWR 以读写方式打开。它还可以通过按位或的方式仙则下面可选模式:O_APPEND :把写入的数据追加在文件的末尾。O_RTUNC:把文件长度设置为0,丢弃已有的内容。 O_CREAT:如果需要,就按参数mode中给出的访问模式创建文件。O_EXCL:与O_CREAT一起使用,确保调用者创建出文件。open调用在成功时返回一个信的文件描述符(它总是一个非负数),失败时返回-1,并设置局部变量errno以指明失败的原因。新文件描述符总是使用未使用的最小值。
2.read系统调用。从与文件描述符fildes相关联的文件里读入nbytes个字节的数据,并把他们放到数据区buf中。它返回实际读入的字节数。
- #include <unistd.h>
- size_t read(int fildes, void *buf, size_t nbytes)
3.write系统调用。把缓冲区buf的前nbytes个字节写入与文件描述符fildes关联的文件中。它返回实际写入的字节数。
- #include<unistd.h>
- size_t write(int fildes, const void *buf, size_t nbytes);
4.close系统调用。终止一个文件描述符fildes与其对应文件之间的关联。文件描述符被释放并能够重新使用。
- #include <unistd.h>
- int close(int fildes);
调用成功返回0 ,出错返回-1.
5.ioctl系统调用。它提供一个用于控制设备及其描述符行为和配置底层服务的接口。
- #include <unistd.h>
- int ioctl(int fildes, int cmd, ...);
ioctl对描述符fildes指定的对象执行cmd参数中给出的操作。