3.1 Linux 文件结构
Linux中,一切都是文件!一切!比较重要的三个设备文件:/dev/console 代表控制台 /dev/tty 代表控制终端 /dev/null 代表空,写向这个设备的数据都将被删除。
inode: 文件除了本身包含的内容以外,他还会有一些名字和属性,即一些“管理信息”,如创建、修改日期和它的访问权限等,这些属性被保存在文件的inode中。对于每个 ext2 分区来说,其在物理磁盘上的布局如图 所示:
从图中可以看到,对于 ext2 文件系统来说,磁盘被划分成一个个大小相同的数据块,每个块的大小可以是1024、2048 或 4096 个字节。其中,第一个块称为引导块,一般保留做引导扇区使用,因此 ext2 文件系统一般都是从第二个块开始的。剩余的块被划分为一个个的块组,ext2 文件系统会试图尽量将相同文件的数据块都保存在同一个块组中,并且尽量保证文件在磁盘上的连续性,从而提高文件读写时的性能。
每个块组都包含以下内容:
3.2 系统调用和设备驱动程序
系统调用不多说,就是通往os本身的接口。
os内核就是一组设备驱动程序,是一些对硬件进行控制的底层接口。为了向用户提供一个统一的接口,设备驱动程序封装了所有与硬件相关的特性。单独一个硬件的特性通过ioctl调用来完成,其他的open read write close 函数都一样。
3.3库函数
直接使用系统调用效率非常低,为了提供更高层的接口,Linux发行了一系列标准函数库,来帮助提高系统效率。下图看出库函数的位置。
3.4底层文件访问(就是系统调用)
文件描述符:每个进程都有一些与自身关联的文件描述符,默认自动打开的文件描述符有:
0---标准输入
1---标准输出
2---标准错误
还可以使用open函数把文件描述符和设备关联起来。文件描述符对每个进程是唯一的。write read open现用现查吧!注意一下open函数带O_CREAT标记时的权限问题,这又涉及到了umask变量。chmod命令可以突破umask变量的限制。
书中的例子用到了一个计时工具,$ TIMEFORMAT=“ ” time ./myexe 来计时myexe的运行时间。
lseek 对读写指针进行设置,fstat stat lsate 系统调用返回相关的文件状态信息,dup dup2函数提供了复制文件描述符的方法,使我们通过两个或者多个不同的文件描述符来访问同一个文件,可以实现在不同的位置对文件进行读写。
3.5标准I/O库
在标准io库中,与底层文件描述符相对等的是流stream,他被实现为指向结构FILE的指针,有三个文件流是自动打开的,stdin、stdout和stderr分别代表标准输入、 标准输出、标准错误输出与底层文件描述符0、1、2相对应。流的理解还应该加深啊!
与文件描述符一样,可用的文件流数目也是有限的,这个限制在stdio.h中的FOPEN_MAX常量定义,最小为8.一些函数如:fopen、fclose、fread、fwrite、fflush、fseek、fgetc、fputc、fgets等等,现用现查吧。
3.6格式化输出和输出
printf(到标准输出)、fprintf(到文件)、sprintf(到字符串)。
(1)d(或i)格式符。用来输出十进制整数,有以下几种用法:
①%d,按整型数据的实际长度输出。
②%md,m为指定的输出字段的宽度。如果数据的位数小于m,则左端补以空格,若大于m,则按实际位数输出。
③%ld(%mld 也可),输出长整型数据。
例如:long a=123456; printf("%ld",a);
(2)o格式符,以八进制数形式输出整数。格式:%o,%mo,%lo,%mlo都可。
(3)x(或X)格式符,以十六进制数形式输出整数。格式:%x,%mx,%lx,%mlx都可。
(4)u格式符,用来输出unsigned型数据,即无符号数,以十进制数形式输出。格式:%u,%mu,%lu都可。
参见:li4-3.c/*无符号数据的输出*/
(5)c格式符,用来输出一个字符。格式:%c,%mc都可。
(6)s格式符,用来输出一个字符串。格式:%s,%ms,%-ms,%m.ns,%-m.ns都可。
(7)f格式符,用来输出实数(包括单、双精度),以小数形式输出。格式:%f,%m.nf,%-m.nf都可。
注意:单精度实数的有效位数一般为7位,双精度为16位。
(8)e(或E)格式符,以指数形式输出实数。格式:%e,%m.ne,%-m.ne都可。
(9)g(或G)格式符,输出一个双精度浮点数。