文件描述符:这通常是一个小的非负整数,内核用以标识一个特定进程正在访问的文件,当内核打开一个现有文件或创建一个新文件时,都返回一个文件描述符,在读写这个文件时,可以使用这个文件描述符</span>
标准输入、标准输出和标准错误
每当运行一个新程序时,所有的shell都为其打开三个文件描述符。如果不做特殊处理,则这三个描述符都连接向终端。大多数shell都提供一个方法,使其中任何一个或所有三个描述符都能重新定向到某一个文件,比如ls>file.list
不带缓冲的IO:函数open、read、write、lsseek以及close提供了不带缓冲的IO,这些函数都使用文件描述符。
以下例子,从标准输入复制到标准输出
#include "apue.h"
#define BUFFSIZE 4096
int main()
{
int n;
char buf[BUFFSIZE];
while((n = read(STDIN_FILENO,buf,BUFFSIZE))>0)
if (write(STDOUT_FILESNO,buf,n)!=n)
err_sys("write error");
if(n<0)
err_sys("read error");
exit(0);
}
头文件<unistd.h>(apue.h包含了此头文件)和两个常量STDIN_FILENO和STDOUT_FILENO是POSIX标准的一部分
两个常量定义在<ubistd.h>头文件中,他们指定了标准输入和标准输出的文件描述符。在POSIX标准中,值分别是0和1.
程序编译好,并这样执行:./a.out > data 那么标准输入是终端,输出则重新定向至文件data,如果文件不存在则会自动创建,键入Ctrl+D终止本次复制。
若以下列方式执行该程序:./a.out < infile > outfile 会将名为infile文件的内容复制到名为outfile文件中
标准IO
标准IO函数为那些不带缓冲的IO函数提供了一个带缓冲的借口,使用标准IO函数无需担心如何选择最佳缓冲区的大小,使用标准IO函数还简化了对输入行的处理,比如标准IO函数fgets读取一个完整的行,而read读取指定字节数。
而最熟悉的标准IO函数就是printf,在调用printf的程序中,总是包含stdio.h文件,该头文件包含了所有标准IO函数的原型。
以下程序是使用标准IO函数,功能类似前者,将标准输入复制到标准输出
#include "apue.h"
#define BUFFSIZE 4096
int main()
{
int c;
while((c=getc(stdin))!=EOF)
if(putc(c,stdout) == EOF)
err_sys("output error");
if(ferror(stdin))
err_sys("input error");
exit(0);
}
函数getc一次读取一个字符,函数putc将此字符写到标准输出。读到输入的最后一个字节时,getc返回常量EOF(该常量在stdio.h中定义)。标准IO常量stdin和stdout也在头文件中定义,分别表示标准输入和标准输出。