一、知识概要
输入/输出是在主存和外部设备之间复制数据的过程。输入操作是从I/O设备复制数据到主存,而输出操作是从主存复制数据到I/O设备。常见的系统调用函数有:
1、 int open(char *filename,int flags,mode_t mode):打开一个一存在的文件或创建一个新的文件。 函数将filename转换成一个文件描述符并返回;flags参数指明如何访问这些文件,有O_RDONLY只读、O_WRONLY只写、O_RDWR可读可写,也可以是一个或多个掩码,如O_CREAT、O_TRUNC、O_APPEND;mode参数指定新文件的访问权限位,其中一共有9种:
S_IRUSR:使用者可以读这个文件 S_IWUSR:使用者可以写这个文件 S_IXUSR:使用者可以执行这个文件
S_IRGRP:使用者所在的组的成员可以读 S_IWGRP:使用者所在的组的成员可以写 S_IXGRP:使用者所在的组的成员可以执行
S_IROTH:其他人可以读这个文件 S_IWOTH:其他人可以写这个文件 S_IXOTH:其他人可以执行这个文件
2、 int close(int fd):关闭一个已打开的文件。fd为要关闭的文件的描述符。
3、 ssize_t read(int fd,void *buf,size_t n):从描述符为fd的当前文件复制最多n个字节到内存位置buf,返回值表示实际传送字节数量。
4、 ssize_t write(int fd,const void *buf,size_t n):从内存位置buf复制最多n个字节到描述符为fd的当前文件,返回值表示实际传送字节数量。
5、 int stat(const char *filename,struct stat *buf):检索关于文件的信息。返回一个包含文件信息的stat的数据结构。
6、 int dup2(int oldfd,int newfd):复制文件描述符表表项oldfd到文件描述符表项newfd,覆盖文件描述符newfd表项以前的内容。
二、代码分析
代码1:
文件内容为:"abcde"
运行结果:
文件描述符表中有三个表项fd1 fd2 fd3,fd2复制到fd3,指向打开的同一个文件,fd1指向打开的另一个文件。fd1读第一个字符到c1中,即'a'。fd2读另一个文件的中的第一个字符'a'到c2,fd3接着读第二个字符'b'到c3中。
代码2:
运行结果: 文件内容为:"abcde"
首先fd1从文件中读取一个字符'a'存放c1,fork后父进程接着读一个字符'b'给c2。而因为子进程完全复制父进程的内容,父、子进程的fd1指向同一个文件,所以子进程fd1接着读第三个字符'c'给c2。
代码3:
创建文件中的内容如下:
fd1指向了一个新创建的文件,名为:"fname",然后往文件里面写入四个字符"pqrs"。fd3也指向这个文件,并在文件末尾写入5个字符"jklmn"。fd2复制fd1,同样在fd1指向的文件末尾加上4个字符"wxyz,覆盖掉fd3写在后面的前四个字符。fd3再往文件中接着上次输入的末尾输入2个字符"ef"。
代码4:
运行结果如下:文件内容为:"abcde"
首先定义一个stat类型的结构体,通过stat函数返回文件的元数据。st_mode中包含了文件访问许可位和文件类型。S_ISREG()判定文件是否为普通文件,S_ISDIR()判定文件是否为目录文件,都不是则为其它类型文件。st_mode与S_IRUSR位做与运算,非0则当前用户可读。