linux应用开发----系统IO入门

68 阅读6分钟

linux应用开发—---设备访问

linux系统的最大特点:"一切皆是文件",linux设备也不例外所以linux设备访问就会转换为文件的访问,

关于文件的访问,在C语言中有标准IO(文件流)的访问方式,但针对设备文件访问我们是要利用系统IO接口来访问的。

1. 相关概念:

  文件:存储在外存储器上的数据集合;
  文件描述符:linux系统中唯一标识一个文件的;
             本质:非负整数;
             获取方式:打开文件;

2. 系统IO用于文件访问的流程步骤:

      ·打开文件,获取文件描述符;
      ·读,写 文件;
      ·关闭文件回收文件描述符;  

3. 常用的系统IO函数:

  1. access函数:是用于确认文件是否存在,当前用户访问权限的文件属性是什么

  ```c#
  	  access
            
        头文件:   #include <unistd.h>
                  #include <fcntl.h>
        函数原型: int access(const char* filepath, int mode);
        函数功能: 用于确认文件是否存在,当前用户访问权限文件属性
        函数参数: filepath: 目标文件路径
                   mode    :  操作方式:取值如下:
                               F_OK      确认文件/目录是否存在 
                               R_OK      确认当前用户是否具有读权限
                               W_OK      确认当前用户是否具有写权限
                               X_OK      确认当前用户是否具有执行权限
        函数返回值:
                     返回 0:   确认的属性是满足的 
                     返回 -1:  确认的属性是不满足的  
                                错误码会存放在errno里  
  ```

  2. open函数:打开或者创建一个文件

  ```c#
        open  
            
        头文件:    #include <unistd.h>
                  #include <fcntl.h>
        函数原型:  int open(const char* filepath, int flages);
                  int open(const char* filepath, int flages, mode_t mode);
        函数功能: 打开或者创建文件
        函数参数:  filepath:  目标文件路径
                  flages    :文件打开方式:取值如下:
  
                            必选项:
                            O_RDONLY      只读方式 
                            O_WRONLY      只写方式
                            O_RDWR        读写方式
                            附加选项(常用):
                            O_CREAT:      创建标志
                            O_APPEND:     追加标志(往往与写操作连用)
                            O_TRUNC:      覆盖标志(往往与写操作连用)
                            ...
        函数返回值:
                   成功 返回 文件描述符 
                   失败 返回 -1:  错误码会存放在errno里 
  ```

  3. read函数:读取文件的内容到内存缓冲区中

  ```c#
        read   
            
        头文件:   #include <unistd.h>
                  #include <fcntl.h>
        函数原型: ssize_t read(int fd,void* buf,size_t count);
        函数功能: 读取文件内容到内存缓冲区buf中
        函数参数:  fd:  目标文件描述符
                  buf: 已申请的内存空间首地址,用于存储读取到的文件内容:
                  count:期望读取的字节数
        函数返回值:
                     成功: 返回实际读取的字节数,
                           0 代表读取到文件末尾
                     失败: 返回 -1,错误码会存放在errno里 
  ```

  4. write函数:写入内存缓冲区中已有的数据到文件描述符所代表的文件中

  ```c#
  write   
        头文件:   #include <unistd.h>
                  #include <fcntl.h>
        函数原型: ssize_t write(int fd,const void* buf,size_t count);
        函数功能: 写入内存缓冲区buf中的数据到fd代表的文件中
        函数参数: fd:  目标文件描述符
                  buf: 已申请的内存空间首地址,用于存储写入到文件中的数据内容:
                  count:写入的字节数
        函数返回值:
                     成功: 返回实际写入的字节数,
                     失败 返回 -1:  错误码会存放在errno里 
  ```

  5. close函数:关闭前面用open函数打开的文件,并释放文件描述符

  ```c#
   close   
        头文件:   #include <unistd.h>
                  #include <fcntl.h>
        函数原型: int close(int fd);
        函数功能: 关闭文件,释放文件描述符
        函数参数: fd:  待关闭的目标文件描述符
        函数返回值:
                     成功: 返回 0,
                     失败 返回 -1:  错误码会存放在errno里 
  ```

  6. lseek函数:移动文件位置指针,用于对文件进行随机读写(经常取SEEK_END参数所获取的返回值来确定文件大小)

  ```c#
  lseek   
        头文件:   #include <unistd.h>
                  #include <fcntl.h>
        函数原型: off_t lseek(int fd, off_t offset, int whence)
        函数功能: 移动文件位置指针,用于对文件进行随机读写
        函数参数: fd:    要操作的文件描述符;
  	            offset:相对于whence 的偏移量:
  	            whence:移动方式,可取以下值:
  			     SEEK_SET:   文件头部
  			     SEEK_CUR:   当前位置
  			     SEEK_END:   文件末尾                       
        函数返回值: 成功:返回文件位置指针想对于文件开头的偏移量,
                   失败 返回 -1:  错误码会存放在errno里   
  ```

  7. mmap/munmap函数:映射/解除映射 文件存储空间到进程的虚拟地址空间

  ```c#
   mmap / munmap 
       
  
   文件内存映射: Linux系统允许将文件/设备存储空间映射到进程的地址空间,一旦映射建立成功,
                 进程对映射后的地址空间的操作,系统会反映到具体的文件/设备。
                 这样可以避免频繁的系统IO调用引起效率下降的问题。
  
    头文件:   #include <sys/mman.h> 
    函数原型:  void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
               int munmap(void *addr, size_t length);
    函数功能: 映射/解除映射 文件存储空间到进程的虚拟地址空间
    函数参数:  addr: 映射的地址空间首地址,NULL 表示让系统决定;
  	         length: 映射的空间大小
  	         prot: 映射的地址空间访问方式,必须和文件打开方式匹配
                       常见取值: PROT_READ
                                PROT_WRITE
                                PROT_NONE
  	         flags: 映射的地址空间的访问标记,常见取如下:
                       MAP_SHARED   对映射区域的数据写入会复制回文件内,而且允许其他映射该文件的进程共享
                       MAP_PRIVATE  对映射区域的写入不会写回原来的文件内容
  	         fd:     需映射的文件描述符
  	         offset: 文件映射的偏移量,通常设置为0,代表从文件最前方开始对应,
                        offset必须是分页大小(4096)的整数倍
           
    函数返回值: 成功: munmap返回 0  mmap返回实际映射的地址
               出错: mmap返回 MAP_FAILED,并将错误码存入 errno 中
  ```

  8. ioctl函数:对设备的输入输出及特性参数进行控制

  ```c#
  ioctl    
  
       ioctl:  ioctl 是设备驱动程序中设备控制接口函数。常用于对于设备的一些特性/参数进行控制,
               ioctl控制功能取决于跟设备有关的请求码。 
  
    头文件:   #include <sys/ioctl.h>
    函数原型: int ioctl(int fd, int request, ...);
    函数功能: 对设备的输入输出及特性参数进行控制
    函数参数: fd:    要操作的设备文件描述符;
         request:与设备相关的请求码(请求命令):
             ...:可变参数,往往取决于request                    
    函数返回值:   成功: 部分请求结果会以返回值返回 ,大部分返回0,
                 失败 返回 -1:  错误码会存放在errno里    
  ```