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里
```