目录
一、什么是系统IO
二、linux基础
1,文件的权限
2,查看文件权限
3,永久切换成超级用户
4,window和linux路径的区别
5,家目录
6,查看权限掩码
三、linux系统的接口函数
1, 文件描述符:
2,文件的打开/新建 man 2 open
3,文件的读取 man 2 read
4,文件的写入 man 2 write
5,文件的关闭
6,获取文件的属性信息
7,修改文件的权限
8,判断文件是否存在
9,设置文件读写的偏移
10,打印分析出错信息
11,文件重定向
12,字符串的拼接和拆分
13,拆分字符串的神器
14,内存映射(获取液晶屏在内存中的首地址)
结论:linux中一切都是文件
键盘 鼠标 触摸屏 蓝牙 wifi这些硬件设备在linux系统中都有驱动文件
如果程序员需要操作读写这些硬件设备,只需要写代码去读写驱动即可
驱动文件就代码你要操作的硬件设备--》所以得出结论 linux中一切都是文件
一、什么是系统IO
linux系统内核给我们程序员提供的接口函数,用来对文件进行读写操作
上位机:比如智能家居系统中面向用户的那个中控系统(平板)
下位机:硬件传感器
文件IO有什么用
例子一:读写文本文件 ---》 读写一个记事本
例子二:读写二进制文件 ---》拷贝一个程序,拷贝一个视频
例子三:读写硬件传感器的数据 ---》液晶屏,触摸屏,蓝牙
二、linux基础
1,文件的权限
可读 可写 可执行 通过二进制编码可以详细的表示文件的三种权限。
修改权限:chmod 777 1.txt 三个7分别表示当前用户,同组用户,其他用户对于该文件的操作权限.
2,查看文件权限
ls -l 结果:-rwxrwxrwx 1 root root 13 Jul 21 20:35 1.txt
分析结果: 第一个字符 - --》表示这是一个普通文件
d --》表示这是一个目录
rwxrwxrwx --》表示该文件的权限
r 读 w 写 x 可执行
注:千万不要在共享路径下修改文件的权限,不准确(或者无法修改),会受到windows系统的干扰
3,永久切换成超级用户
sudo -s
切换回普通用户 su 用户名
4,window和linux路径的区别
window有磁盘分区: C:usrerxxxyyy linux路径:没有磁盘分区,只有一个根目录 /
5,家目录
linux给不同的用户都创建了一个文件夹(文件夹的名字跟用户名相同) -->这个特殊的文件
夹叫做家目录
切换到家目录: cd /home/xxx xxx就是你自己的用户名
或者 cd ~ ~等价于/home/xxx
或者 cd 回车 自动进入家目录
6,查看权限掩码
查看掩码值 umask
三、linux系统的接口函数
1, 文件描述符:
分配规则:第一个:0 1 2已经默认被键盘,液晶屏占用了,只能从3开始分配
第二个:linux系统总是把目前没有被占用的最小的文件描述符分配给你
2,文件的打开/新建 man 2 open
注:linux中所有的函数,只要参数需要用到多个宏定义,都是使用按位或连接起来
#include
#include
#include
int open(const char *pathname, int flags);
返回值:成功 --》返回文件描述符
失败 --》返回-1
参数:pathname --》你要打开的那个文件的路径名
flags --》O_RDonLY 只读
O_WRonLY 只写
O_RDWR 可读写
情况一 : 你想使用的权限跟文件本身的权限不一致,会打开失败
你想O_RDWR但是文件本身是只读/只写 --》会导致失败
情况二:你想用O_RDONLY只读的方式打开文件,此时调用write写 入文件是不成功的
O_APPEND 以追加的方式打开文件
O_CREAT 新建文件
O_EXCL 跟O_CREAT配合使用,表示如果文件存在就失败退出 不新 建,不存在就新建
O_TRUNC 跟O_CREAT配合使用,表示如果文件存在就清空覆盖掉原 来的文件
int open(const char *pathname, int flags, mode_t mode);
参数:mode --》你创建一个文件的时候,顺便给这个设置一个权限
注:设置权限需要减去umask掩码值才是最后的权限
3,文件的读取 man 2 read
注: ssize_t和size_t都是用typedef给长整型取的别名
#include
ssize_t read(int fd, void *buf, size_t count);
返回值(重点):成功 --》返回成功读取到的字节数
如果一个文件读取完毕,再次调用read读取,read返回0个字节
失败 --》-1
参数:fd --》 你要读取的那个文件的文件描述符
buf --》 存放你读取到的内容
count --》 你打算读取多少字节的数据
4,文件的写入 man 2 write
ssize_t write(int fd, const void *buf, size_t count);
返回值:count写多少,返回值就是多少
参数:fd --》 你要写入的那个文件的文件描述符
buf --》存放你要写入的内容
count --》你打算写入多少字节的数据
write(fd,"hello",5) //返回值是5
write(fd,"hello",10) //返回值是10
write(fd,"hello",100) //返回值是100
注:count的值请你不要乱瞎写
5,文件的关闭
int close(int fd);
返回值:成功 0 失败 -1
参数:fd --》你要关闭的文件描述符
6,获取文件的属性信息
获取大小,权限,类型
int stat(const char *pathname, struct stat *buf);
返回值:成功 0 失败 -1
参数:pathname --》文件路径名
buf --》结构体指针,用来存放获取到文件属性信息
struct stat
{
mode_t st_mode; //保存文件的类型,权限
off_t st_size; //保存文件大小
}
用途一: 获取文件大小
st_size 里面就是大小
用途二:获取权限
S_IRWXU //当前用户可读,可写,可执行
S_IRWXG //同组用户可读,可写,可执行
S_IRWXO //其他用户可读,可写,可执行
struct stat mystat;
if(mystat.st_mode&S_IRUSR)
printf("这个文件对于当前用户是可读的!n");
用途三:判断文件类型
S_IFSOCK 0140000 套接字
S_IFLNK 0120000 软链接
S_IFREG 0100000 普通文件
S_IFBLK 0060000 块设备
S_IFDIR 0040000 目录
S_IFCHR 0020000 字符设备
S_IFIFO 0010000 管道
写法一:与运算判断
switch(mystat.st_mode&S_IFMT)
{
case S_IFREG: //普通文件
break;
case S_IFDIR: //目录文件
}
写法二:宏函数判断
S_ISDIR(m) 目录
S_ISCHR(m) 字符设备
S_ISBLK(m) 块设备
S_ISFIFO(m) 管道
S_ISLNK(m) 软链接
S_ISSOCK(m) 套接字
if(S_ISREG(mystat.st_mode))
printf("这是个普通文件!n");
7,修改文件的权限
int chmod(const char *pathname, mode_t mode);
返回值:成功 0 失败 -1
参数:pathname --》文件路径名
mode --》八进制数,表示权限0777
注:chmod命令修改权限以及chmod函数修改权限,都不需要考虑掩码umask
open(新建一个文件,设置权限) 需要考虑计算掩码
8,判断文件是否存在
int access(const char *pathname, int mode);
返回值:文件存在 0 不存在 -1
参数:pathname --》文件路径名
mode --》R_OK //判断文件是否可读
W_OK //判断文件是否可写
X_OK //判断文件是否可执行
F_OK //判断文件是否存在
9,设置文件读写的偏移
作用:程序员可以依据自己的实际需要,往文件的任何位置读取/写入内容
off_t lseek(int fd, off_t offset, int whence);
返回值:成功 返回当前偏移位置距离文件开头的字节数
失败 -1
参数:fd --》你要设置读写偏移的文件的文件描述符
offse --》你要设置的读写偏移量,字节
whence --》你打算从文件的哪个位置开始偏移
SEEK_SET //起始位置
SEEK_CUR //当前位置,动态变化
SEEK_END //末尾位置
比如: lseek(fd,10,SEEK_SET); //把读写偏移设置成从起始位置往后偏移10个字节
用法一:
lseek去设置读写偏移量
用法二:
lseek求文件的大小
lseek(fd,0,SEEK_END);
10,打印分析出错信息
#include
void perror(const char *s);
参数:s --》你写的打印信息
底层原理:
linux系统把所有常见的错误类型用宏定义定义成一个个错误码
文件不存在 1
权限不够 2
内存溢出 3
....
linux的errno.h中有定义全局变量 int errno用来记录保存当前的错误码
perror源码中依据errno中的错误码找到错误的具体原因
11,文件重定向
重定向:重新确定文件读写(IO)的方向
int dup(int oldfd); //给原来的文件描述符分配一个新的文件描述符
返回值:成功 返回一个新的文件描述符
失败 -1
参数;oldfd --》原本的文件描述符
int dup2(int oldfd, int newfd); //重点,重点程序员指定分配一个新的文件描述符
返回值:成功 返回一个新的文件描述符
失败 -1
参数:oldfd --》原本的文件描述符
newfd --》程序员指定分配的新文件描述符
12,字符串的拼接和拆分
int sprintf(char *str, const char *format, ...);
参数:str --》存放拼接后的结果
format --》你打算按照什么格式去拼接数据
int sscanf(const char *str, const char *format, ...);
参数:str --》你要拆分的字符串
format --》你打算按照什么格式去拆分字符
13,拆分字符串的神器
har *strtok(char *str, const char *delim);
返回值:切割得到的字符串
切割完毕,切割失败 返回NULL
参数:str --》你要切割的字符串
delim --》切割的标准(你打算用哪些字符作为字符串切割的分隔字符)
总结:以后写代码--》拼接字符串sprintf
切割拆分字符串strtok
14,内存映射(获取液晶屏在内存中的首地址)
#include
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
返回值:成功 返回液晶屏的首地址
失败 NULL
参数: addr --》一般设置为NULL 表示由操作系统自动分配硬件的首地址
length --》你想映射的液晶屏地址大小 800*480*4
prot --》内存区域的访问权限
PROT_READ //可读
PROT_WRITE //可写
flags --》你映射的地址空间是否可以被共享
MAP_SHARED 可以共享
MAP_PRIVATE 不可以共享
fd --》你要映射的硬件设备的文件描述符
offset --》地址偏移,一般设置为0
解除映射
int munmap(void *addr, size_t length);
参数:addr --》你之前映射得到的首地址
length --》映射的内存大小



