特别文件:字符模式和块模式

如前所述,这样的文件既可以被您的系统创建,又可以被外设创建。我们也提到了块模式文件的内容会被存入缓冲区而字符模式文件则不然。为了显示这一点,把软盘插入驱动器并键入如下命令两次:

$ dd if=/dev/fd0 of=/dev/null

您应该可以看到如下现象:命令被第一次调用的时候,这个软盘的内容全被被读入。第二次执行命令的时候系统就不会再读取软盘内的任何信息。这是因为软盘的内容在第一次调用命令  –– 的时候就已经都被读入缓冲区了,而软盘内容在两次操作间没有发生任何变化。

但是现在,如果您想通过这种方法打印一个大文件(是的,这是可以实现的):

$ cat /a/big/printable/file/somewhere >/dev/lp0

不论您执行了一次命令,两次命令还是五十次命令,命令执行的时候都是一样长的。这是因为 /dev/lp0 是一个字符模式文件,它的内容是不会被放入缓冲区的。

块模式文件被放入缓冲区这一事实还带来了一个非常好的副作用:不光读操作被放入缓冲区,写操作也同样被放入缓冲区了。这使得对磁盘的写操作可以异步执行:当您把一个文件写入磁盘的时候,写操作并不是即时执行的。只有在 Linux 内核决定执行写操作到硬件之后它才会被执行。

最后,每个特殊文件都有一个主要次要编号。因为特殊文件的大小是无关紧要的,所以它们被显示在 ls -l 输出的文件尺寸处。

ls -l /dev/ide/host0/bus0/target0/lun0/disc /dev/printers/0
brw-------  1 root root 3, 0 dic 31  1969 /dev/ide/host0/bus0/target0/lun0/disc
crw-rw----  1 lp   sys  6, 0 dic 31  1969 /dev/printers/0

这里,/dev/ide/host0/bus0/target0/lun0/disc 的主要和次要号分别为3和0。文件 /dev/printers/0 的则是6和0。需要注意的是每类文件都有特殊的编号。也就是说存在主要次要编号分别是3和0的字符模式文件(这个文件确实存在:/dev/pty/s0),并且类似地也存在一个主要次要号文分别是6和0的块模式文件。这些号码之所以存在的原因非常简单:这使得内核正确地关联操作和文件(也就是说,这些文件指向的外设):您并不使用相同的方法处理软驱和 SCSI 硬盘。