【Linux学习笔记】通用I/O模型概述

来源:互联网 发布:外星文明不存在 知乎 编辑:程序博客网 时间:2024/05/20 02:53

    

      在Linux系统中,“一切皆文件”的概念是非常经典的。尤其为编程人员带来了方便。当所有的I/O操作都可以以一种操作文件的形式执行时,我们就可以以一组通用的I/O系统调用来完成我们想要执行的I/O操作(其中的操作对象包括:管道、FIFO、设备、终端、socket、文件)。

 

      为了标记和区分打开的文件,系统引入了文件描述符的概念。文件描述符:就是一个用来指代所打开文件的非负整数,一般很小。其中有3个文件描述符是系统定义的(即我们常用的3个标准文件描述符):

      标准输入:------ 0 ------ stdin    ------ STDIN_FILENO

      标准输出:------ 1 ------ stdout ------ STDOUT_FILENO  

      标准错误:------ 2 ------ stderr  ------ STDERR_FILENO

     

      其实,在我们日常的shell操作中,这三个文件描述符始终是打开的(指向打开的终端)。通过shell运行的程序也会继承当前终端的这三个文件描述符的副本。

 

      该如何完成具体的I/O操作呢?!当然是依靠系统调用了,下面介绍4个文件操作函数,通过这4个系统调用即可完成对所有类型文件的I/O操作。

      1、打开文件: int open(const char *pathname, int flags, mode_t mode);

           pathname参数所指示要打开的文件;

           flags参数指定文件的打开方式,如果不存在还可以通过掩码操作设置为创建;

           mode参数指定了创建文件时的文件的访问权限(没有新创建文件的话,可以忽略mode)。

       返回值:成功返回指示pathname文件的文件描述符fd,失败返回-1。

  -->需要包含的头文件:

      #include <sys/types.h>

      #include <sys/stat.h>

      #include <fcntl.h>

 

      2、读取文件: ssize_t read(int fd, void *buf, size_t count);

           fd参数为open()函数所打开要读取文件的文件描述符;

           buf参数为预先准备存储转换空间;

           count参数为每次最多读取的字节数,也就是buf空间的大小。

        返回值:每次读取操作实际读取的字节数。如果无字节可读(EOF),则返回0, 失败返回-1。            

  -->需要包含的头文件:

      #include <unistd.h>

 

      3、写入文件:ssize_t write(int fd, const void *buf, size_t count);

          fd参数为open()函数所打开要写入文件的文件描述符;

          buf参数为预先准备存储转换空间;

          count参数为每次要把至多count个字节写入到fd指示的文件中。

       返回值:每次写入操作实际写入的字节数,有可能小于count, 失败返回-1。

  -->需要包含的头文件:

      #include <unistd.h>

 

      4、关闭文件:int close(int fd);

            fd参数为已经打开的文件的文件描述符,读取写入操作完成后,需要用close()释放fd和相关的内核资源。

          返回成功or失败,-1表示失败。

  -->需要包含的头文件:

      #include <unistd.h>

 

 

 一个简单的小例子:(从一个文件读取内容,拷贝到另一个文件中)

#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#ifndef BUF_SIZE #define BUF_SIZE 1024#endifint main (int argc, char **argv){int inputFd, outputFd, openFlags;mode_t filePerms;ssize_t numRead;char buf[BUF_SIZE];if(argc != 3 || strcmp(argv[0], "--help") == 0){printf("%s old_file_name new_file_name.", argv[0]);exit(-1);}inputFd = open(argv[1], O_RDONLY);if(inputFd == -1){printf("open file %s failed.", argv[1]);exit(-1);}openFlags = O_CREAT | O_WRONLY | O_TRUNC;filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;        //rw-rw-rw-outputFd = open(argv[2], openFlags, filePerms);if(outputFd == -1){printf("open file %s failed.", argv[2]);exit(-1);}while ((numRead = read(inputFd, buf, BUF_SIZE)) > 0){if (write(outputFd, buf, numRead) != numRead){perror("couldn't write whole buffer.");exit(-1);}}if(numRead == -1){printf("write file %s failed.", argv[2]);exit(-1);}if(close(inputFd) == -1){perror("close input failed.");}if(close(outputFd) == -1){perror("close output failed.");}return 0;}


 

 //未完待续.....

//4个通用文件操作函数的详细介绍

1 0
原创粉丝点击