文件描述符通常是一个较小的非负整数,内核用以标识一个特定进程正在访问的文件。当内核打开一个现有文件或创建一个新文件时都会返回一个文件描述符。在读、在写这个文件时可以使用这个文件描述符。
int main(int argc,char* argv[]){
int fd=open(argv[1],O_RDONLY); //fd返回的就是文件描述符
if(fd==-1){
E_MSG("open",-1);
}
printf("file %s open success\n",argv[1]);
close(fd);
return 0;
}
常见的文件描述符有:
stdin
):值为0,用于读取标准输入。stdout
):值为1,用于写入标准输出。stderr
):值为2,用于写入标准错误。标准输入(Standard Input),标准输出(Standard Output)和标准错误(Standard Error)是在操作系统中用于输入和输出的预定义流。
stdin
):标准输入是程序默认从用户获取输入数据的流。它通常关联着用户的键盘输入。程序可以从标准输入读取数据,以便进行处理或响应用户输入。在UNIX和类UNIX系统中,标准输入的文件描述符值为0。stdout
):标准输出是程序默认将结果输出的流。它通常关联着显示屏或控制台窗口。程序可以使用标准输出来显示结果、打印消息等。在UNIX和类UNIX系统中,标准输出的文件描述符值为1。stderr
):标准错误是程序默认将错误消息输出的流。它通常也关联着显示屏或控制台窗口,但与标准输出分开,可以将错误信息与正常输出区分开来。程序可以使用标准错误来报告错误、警告等。在UNIX和类UNIX系统中,标准错误的文件描述符值为2。标准输入、标准输出和标准错误通常在命令行界面和终端应用程序中使用。例如,通过键盘输入的数据将作为标准输入供程序读取,程序的输出将通过标准输出显示给用户,而错误消息将通过标准错误显示。
在编程语言中,可以使用相应的方法或函数来读取标准输入、写入标准输出和写入标准错误。例如,在C语言中,可以使用scanf
来读取标准输入,printf
来写入标准输出,fprintf
来写入标准错误。
open、read、write、lseek、close
都提供了不带缓冲的I/O。这些文件都使用文件描述符。
#include "apue.h"
#define BUFFSIZE 4096 //读取和写入的缓冲区大小为4096字节
int main(void){
int n; //保存每次读取的字节数
char buf[BUFFSIZE]; //定义字符数组作为缓冲区
while((n=read(STDIN_FILENO,buf,BUFFSIZE))>0){ //使用循环不断从标准输入读取数据,读到末尾时返回0
if(write(STDOUT_FILENO,buf,n)!=n){ //将读取到的数据作为标准输出写出,若写入的字节数不等于读取的字节数,发生错误
err_sys("write error");
}
}
if(n<0){
err_sys("read error");
}
exit(0);
}
vi mycp.c //创建文件,将上述代码粘贴进入
gcc mycp.c -o mycp -l apue //编译文件
./mycp > data //验证1,终端为标准输入,data文件为标准输出
./mycp < data >outdata //验证2,将data文件复制到outdata文件
标准I/O提供了一种更高级,更方便的方式处理输入输出,为不带缓冲的I/O函数提供了带缓冲的接口。无需担心如何选取最佳的缓冲区大小。反之上面的代码自己设置了缓冲区。在C语言中,常用的标准I/O有:
scanf
和fscanf
:从标准输入或文件中读取格式化输入。printf
和fprintf
:将格式化的数据输出到标准输出或文件中。getchar
和fgetc
:从标准输入或文件中逐个字符地读取输入。putchar
和fputc
:将字符输出到标准输出或文件中。gets
和fgets
:从标准输入或文件中逐行读取输入。puts
和fputs
:将字符串输出到标准输出或文件中。标准I/O的优点包括:
更方便的输入和输出:可以使用格式化字符串进行输入和输出,更易于处理不同类型的数据。
缓冲机制:标准I/O库会对数据进行缓冲,提高读写效率。
支持流重定向:可以将输入和输出重定向到文件或其他设备。
#include "apue.h"
int main(void){
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);
}
vi mycp1.c
gcc mycp1.c -o mycp1 -l apue
./mycp1 > data //跟不带缓冲IO里面实现功能一致
./mycp1 < data > outdata
./mycp1 > data //跟不带缓冲IO里面实现功能一致
./mycp1 < data > outdata