导言:
I/O输入输出是在主存和外部设备之间复制数据的过程。输入操作是从I/O设备复制数据到主存,而输出操作是从主存复制数据到I/O设备
I/O函数:
标准I/O:
c语言定义了一组高级输入输出函数,成为标准I/O库,为程序员提供了Unix I/O的较高级别的替代。这个库提供了打开和关闭文件的函数(fopen和fclose)、读和写字节的函数(fread和fwrite)、读和写字符串的函数(fgets和fputs),以及复杂的格式化的I/O函数(scanf和printf)。
标准I/O库将一个打开的文件模型化为一个流。对于程序员而言,一个流就是一个指向FILE类型的结构的指针。每个ANSI C程序开始时都有三个打开的流 stdin、stdout和stderr,分别对应于标准输入、标准输出和标准错误。
Unix I/O函数:
Unix I/O模型是在操作系统内核中实现的。应用程序可以通过诸如open、close、lseek、read、write和stat这样的函数来访问Unix I/O。RIO和标准I/O函数都是基于Unix I/O函数来实现的。
read和write函数:
应用程序时通过分别调用read和write函数来执行输入和输出的
ssize_t read(int fd,void *buf,size_t n);#参1描述符,参2字符串地址,参3读入长度ssize_t write(int fd,const void *buf,size_t n);#参1描述符,参2字符串地址,参3写入长度
read函数从秒输入为fd的当前文件位置复制最多n个字节到内存位置buf。返回值-1表示一个错误,而返回值0表示EOF。否则,返回值表示的是实际传送的字节数量。
write函数从内存位置buf复制至多n个字节到描述符fd的当前文件位置。
一个一字节一字节的从标准输入复制到标准输出的读取程序read:
#include<stdio.h>#include <unistd.h>int main(){printf("client: PID %d\n",getpid());char c;while(read(STDIN_FILENO,&c,1)!=0)write(STDOUT_FILENO,&c,1);}
一个测试:
我们都知道,linux一切皆文件
运行上面的read程序:
pid为21270
在/proc/pid目录下存有该程序的信息,其中fd中有标准输入输出的软连接,我们可以通过这个软连接获得到描述符,然后用ioctl函数向其中写入数据,如果输入内容回显了说明read函数确实从标准输入中读取了数据:
/*written by evoa(很感谢evoa师傅)编译命令:gcc - g evoa_tql.c evoa_tql*/#include <stdio.h>#include <fcntl.h>#include <termios.h>#include <sys/ioctl.h>#include <unistd.h>char *progname;static int usage() {printf("Usage: %s ttydev text\n", progname);return 2;}int main(int argc, char **argv) {int fd, argi;char *term = NULL;char *text = NULL;int t[2]={65,13},len=2; #写入65,13对应A与回车符progname = argv[0];argi = 1;if (argi < argc)term = argv[argi++];else {fprintf(stderr, "%s: no tty specified\n", progname);return usage();}if (argi < argc){text = argv[argi++];printf("text:%p,%d",&t,argi);}else {fprintf(stderr, "%s: no text specified\n", progname);return usage();}if (argi != argc) {fprintf(stderr, "%s: too many arguments\n", progname);return usage();}fd = open(term, O_RDONLY);if (fd < 0) {perror(term);fprintf(stderr, "%s: could not open tty\n", progname);return 1;}for (int i=0;i<len;i++){if (ioctl(fd, TIOCSTI, &t[i])) {perror("ioctl");return 1;}text++;}return 0;}
运行

可以看到确实输出了大写的A,证明成功!
