您或许想知道,当我们逐行或逐字符地读时,对 setvbuf 的调用是如何起作用的。好吧,下面就此进行介绍:因为我们在使用 stdio 库,库中更低级别的程序从磁盘一次一块地读取数据 — 这里块的大小对应于我们已经指定的缓冲区大小 — 并将它置入我们的缓冲区 inbuf。然后,每当我们调用 fgets() 或 getc(),数据被传递到我们的程序变量(line 或 c)中。因为以更大的块从磁盘读取数据效率更高,而将数据从内存中的一个位置(inbuf)传递到另一个位置(我们的程序变量)是相当快的,因此输入输出更快 — 至少理论上如此。实际上,缓冲可能发生在其它不同的级别,例如硬盘本身、控制器或内核磁盘驱动设备驱动程序,所以我们的工作可能对性能影响不大。使用 setvbuf() 甚至可能使代码运行得更慢。我们想说的是:性能调整是一件麻烦而复杂的事,对任何更改都要进行测试以了解它们是否有影响。
以注释“end main loop”开始的行
我们检查起始页号和结束页号是否大于总页数,若是,则给出适当的消息。然后检查输入流上是否发生错误,若是,则给出消息。最后,关闭输入流,清空输出流,如果输出流是管道,则用 pclose() 函数关闭它。这样做的结果是向 lp 进程发送 EOF,lp 随之终止。
如果输出流是标准输出,并且没有被重定向至文件或管道,则选定的页将出现在屏幕上。
如果输出流是标准输出,并且被重定向至一个文件,则选定的页将在该文件中。
如果输出流是标准输出,并且由管道输送至另一个进程(在命令行级别),则选定的页将成为该进程的输入。例如,您可以将输出由管道输送至分页程序“less”,这样您可以一次一页地查看输出并来回滚动。
如果输出流由管道输送至 lp(从程序内部使用“-dDestination”选项和 popen()完成),这些选定的页将在给定的打印目的地(假设已启用)打印出来。
使用 selpg
为了演示最终用户可以如何应用我们所介绍的一些原则,下面给出了可使用的 selpg 命令字符串示例:
$ selpg -s1 -e1 input_file
该命令将把“input_file”的第 1 页写至标准输出(也就是屏幕),因为这里没有重定向或管道。
$ selpg -s1 -e1 < input_file
该命令与示例 1 所做的工作相同,但在本例中,selpg 读取标准输入,而标准输入已被 shell/内核重定向为来自“input_file”而不是显式命名的文件名参数。输入的第 1 页被写至屏幕。
$ other_command | selpg -s10 -e20
“other_command”的标准输出被 shell/内核重定向至 selpg 的标准输入。将第 10 页到第 20 页写至 selpg 的标准输出(屏幕)。
$ selpg -s10 -e20 input_file >output_file
selpg 将第 10 页到第 20 页写至标准输出;标准输出被 shell/内核重定向至“output_file”。
$ selpg -s10 -e20 input_file 2>error_file
selpg 将第 10 页到第 20 页写至标准输出(屏幕);所有的错误消息被 shell/内核重定向至“error_file”。请注意:在“2”和“>”之间不能有空格;这是 shell 语法的一部分(请参阅“man bash”或“man sh”)。
$ selpg -s10 -e20 input_file >output_file 2>error_file
selpg 将第 10 页到第 20 页写至标准输出,标准输出被重定向至“output_file”;selpg 写至标准错误的所有内容都被重定向至“error_file”。当“input_file”很大时可使用这种调用;您不会想坐在那里等着 selpg 完成工作,并且您希望对输出和错误都进行保存。
$ selpg -s10 -e20 input_file >output_file 2>/dev/null
selpg 将第 10 页到第 20 页写至标准输出,标准输出被重定向至“output_file”;selpg 写至标准错误的所有内容都被重定向至 /dev/null(空设备),这意味着错误消息被丢弃了。设备文件 /dev/null 废弃所有写至它的输出,当从该设备文件读取时,会立即返回 EOF。
$ selpg -s10 -e20 input_file >/dev/null
selpg 将第 10 页到第 20 页写至标准输出,标准输出被丢弃;错误消息在屏幕出现。这可作为测试 selpg 的用途,此时您也许只想(对一些测试情况)检查错误消息,而不想看到正常输出。
$ selpg -s10 -e20 input_file | other_command
selpg 的标准输出透明地被 shell/内核重定向,成为“other_command”的标准输入,第 10 页到第 20 页被写至该标准输入。“other_command”的示例可以是 lp,它使输出在系统缺省打印机上打印。“other_command”的示例也可以 wc,它会显示选定范围的页中包含的行数、字数和字符数。“other_command”可以是任何其它能从其标准输入读取的命令。错误消息仍在屏幕显示。
$ selpg -s10 -e20 input_file 2>error_file | other_command
与上面的示例 9 相似,只有一点不同:错误消息被写至“error_file”。