Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1742334
  • 博文数量: 438
  • 博客积分: 9799
  • 博客等级: 中将
  • 技术积分: 6092
  • 用 户 组: 普通用户
  • 注册时间: 2012-03-25 17:25
文章分类

全部博文(438)

文章存档

2019年(1)

2013年(8)

2012年(429)

分类: 系统运维

2012-03-28 13:11:13

迄今我们已经说过两个不同的文件类型:普通文件和目录。UNIX系统的多数文件都是普通文件或者目录,但也有其它的文件类型。文件类型有:


1、普通文件。最普遍的文件类型,以某种格式包含数据。对于UNIX内核而言,数据是文本还是二进制没有区别。一个普通文件内容的任何任何解释都留给处理 这个文件的程序。一个显著的例外是二进制可执行文件。为了执行一个程序,内核必须了解它的格式。所有的二进制可执行文件都遵守一个允许内核来找到在哪里载 入一个程序的代码和数据的格式。


2、目录文件。一个包含其它文件名和这些文件的信息指针的文件。任何从一个有目录文件读权限的进程都可以读取这个目录的内容,但只有内核才能直接向一个目录文件写入。进程必须使用这章介绍的来对一个目录进行修改。


3、块特殊文件。一种提供以固定尺寸单位的缓冲I/O方式访问设备(比如硬盘)的文件类型。


4、字符特殊文件。一种提供以可变尺寸单位的未缓冲I/O方式访问设备的文件类型。在一个系统上的所有设备不是块特殊文件就是字符特殊文件。


5、FIFO。一种用于进程间通信的文件类型。它有时被称为命令管道。我们在15.5节讨论FIFO。


6、套接字。一种用于进程间网络通信的文件类型。一个套接字也可以用来在同一主机上的进程间的非网络通信。我们在16章使用套接字来进程进程间的通信。


7、符号链接。一种指向另一个文件的文件类型。我们在4.16节更深入讨论符号链接。


一个文件的类型编码在stat结构体的st_mode成员里。我们可以使用下表的宏来决定文件类型。这些宏的参数都是stat结构体的st_mode成员:

里的文件类型宏
文件类型
S_ISREG() 普通文件
S_ISDIR() 目录文件
S_ISCHR() 字符特殊文件
S_ISBLK() 块特殊文件
S_ISFIFO() 管道或FIFO
S_ISLNK() 符号链接
S_ISSOCK() 套接字


POSIX.1允许系统实现把进程间通信(interprocess communication,IPC)对象,比如消息队列和信号量作为文件。在下表中的宏允许我们根据stat结构体决定IPC对象的类型。这些实验室与 上表中的不同,它们的参数是指向stat结构体的指针,并非以st_mode成员:

里的IPC类型宏
对象类型
S_TYPEISMQ() 消息队列
S_TYPEISSEM() 信号量
S_TYPEISSSHM() 共享内存对象


消息队列、信号量和共享内存对象会在第15章讨论。尽管如此,在本文讨论的UNIX实现里没有一个把这些对象表示成文件。


下面的例子打印每个命令行参数的文件类型:


  1. #include <sys/stat.h>

  2. int main(int argc, char *argv[])
  3. {
  4.     int i;
  5.     struct stat buf;
  6.     char *ptr;

  7.     for (i = 1; i < argc; i++) {
  8.         printf("%s: ", argv[i]);
  9.         if (lstat(argv[i], &buf) < 0) {
  10.             printf("lstat error\n");
  11.             continue;
  12.         }
  13.         if (S_ISREG(buf.st_mode))
  14.             ptr = "regular";
  15.         else if (S_ISDIR(buf.st_mode))
  16.             ptr = "directory";
  17.         else if (S_ISCHR(buf.st_mode))
  18.             ptr = "character special";
  19.         else if (S_ISBLK(buf.st_mode))
  20.             ptr = "block special";
  21.         else if (S_ISFIFO(buf.st_mode))
  22.             ptr = "fifo";
  23.         else if (S_ISSOCK(buf.st_mode))
  24.             ptr = "socket";
  25.         else if (S_ISLNK(buf.st_mode))
  26.             ptr = "symbolic link";
  27.         else
  28.             ptr = "** unknown mode **";
  29.         printf("%s\n", ptr);
  30.     }
  31.     exit (0);
  32. }

我们特别使用了lstat函数而不是stat函数,来查明符号链接。如果我们使用stat函数,我们不能看到符号链接。

为了在Linux系统上编译这个程序,我们必须定义_GNU_SOURCE来包含S_ISSOCK宏的定义。


历史上,UNIX系统的早期版本并没有提供S_ISXXX宏。相反,我们必须对st_mode值和S_IFMT掩码进行逻辑与操作,然后比较与操作后的结 果和名为S_IFxxx的常量。多数系统在里定义了这个掩码和相关常量。如果我们检查这个文件,我们会发现 S_ISDIR宏的定义类似于:
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)


我们已经说过普通文件是占主导地位的,但看看在给定系统上每个文件类型的文件百分比是很有趣的。下表展示了使用Linux系统作为一个单一用户的工作站的数量和百分比。这个数据是通过4.21节的程序获得的:

不同文件类型的计数和百分比
文件 数量 百分比
普通文件 226,856 88.22%
目录 23,017 8.95
符号链接 6,442 2.51
字符特殊 447 0.17
块特殊 312 0.12
套接字 69 0.03
FIFO 1 0.00
阅读(802) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~