Linux分层结构
应用层:标准IO、c、c++、网络编程
内核层:进程管理系统(进程调度、进程管理)、内存管理系统、驱动
物理层:STM32
Linux各类文件
struct file
这个结构体再文件被操作时创建
struct file_operations
这个结构体的成员几乎都是函数指针,用于做统一化管理
b: 块设备文件(block)
c: 字符设备文件(character)
d: 目录文件(directory)
l: 链接文件(软链接)(link)
p: 管道文件(命令管道)(pipe)
-: 普通文件(regular)
s: 套接字文件(socket)
IO基础知识
标准文件IO | 系统文件IO | |
---|---|---|
存放位置 | 存放在c标准库 | 存放在内核 |
移植性 | 具有良好的移植性 | 不可移植 |
使用状态 | 通常在用户态下使用 | 通常在内核态下使用 |
级别(离底层越近越低级,例如c语言可直接和硬件打交道,是低级语言) | 高级函数,用于应用层 | 低级函数,用于内核层 |
效率 | 执行效率高 | 执行效率低 |
文件操作在用户态和内核态下交互次数少;==能够使用标准IO的情况下不要使用系统IO;==
能够使用标准IO就一定可以使用系统IO,能使用系统IO不一定可以使用标准IO;
系统IO
系统IO基础知识
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*
功能:打开文件
参数1:待打开的文件名称及其路径
参数2:打开文件的方式(至少有一个,且前三个互斥)
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
O_APPEND 追加
O_CREAT 若文件不存在则创建,存在直接打开
O_TRUNC 若文件存在则清空
参数3:只有文件被创建时才会生效,用于设置文件的权限;若被创建时不设置,则权限随机;若文件存在,则此参数无效;
返回值:成功返回文件描述符(大于0,一般大于3;0 1 2已经被标准输入 标准输出 标准出错占用了) 失败返回-1且errno被自动设置
文件描述符:本质就是数组下标,将文件指针以数组形式存储,当我需要访问文件时,只需要下标值就可访问对应文件
*/
int open(const char* pathname, int flags);
int open(const char* pathname, int flags, mode_t mode);
#include <unistd.h>
/*
功能:从文件读取数据
参数1:待读取文件的文件描述符
参数2:存储读取的数据
参数3:将要读取的字节数
返回值:成功读取的字节数 返回 0 表示到达文件末尾或者无内容 失败返回 -1,且errno被自动设置
*/
ssize_t read(int fd, void *buf, size_t count);
#include <unistd.h>
/*
功能:从文件写入数据
参数1:待写入文件的文件描述符
参数2:待写入的数据
参数3:将要写入的字节数
返回值:成功写入的字节数 失败返回 -1,且errno被自动设置
*/
ssize_t write(int fd, const void *buf, size_t count);
#include <unistd.h>
/*
功能:关闭文件(一定要执行的操作)
参数:待关闭文件的文件描述符
返回值:成功返回0,失败返回-1(一般不会操作)
*/
int close(int fd);
系统IO基础应用案例
#ifndef __HEAD_H
#define __HEAD_H
#include <stdio.h>
...
#endif
#include "head.h"
int main(int argc, char* argv[])
{
//以只读方式打开文件
int fd_r = open("osfile.c", O_RDONLY);
if(fd_r < 0)
{
printf("osfile.c open fail:%s\n", strerror(errno)); //采用标准出错,输出对应错误信息的宏
//perror("osfile.c open fail:");
return -1;
}
int fd_w = open("1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0644); //0644为创建文件时设定的权限
if(fd_w < 0)
{
perror("1.txt open fail");
return -1;
}
char buf[100]; //创建一个缓冲区
while(1)
{
bzero(buf, sizeof(buf)); //清空缓冲区
//memset(buf, 0, sizeof(buf));
int len = read(fd_r, buf, sizeof(buf)-1); //-1是没有 \0 造成的,少读取一个
if(len <= 0)
{
break;
}
write(fd_w, buf, len);
}
close(fd_w);
close(fd_r);
return 0;
}
//diff 1.txt osfile.c 比较两个文件是否相同 若相同则会没有返回
标准IO
标准IO基础知识
#include <stdio.h>
/*
功能:打开文件
参数1:待打开文件
参数2:文件打开方式
r: 只读
r+: 读写,但文件必须存在
w: 只写
w+: 读写,不存在就创建,存在则将文件内容清空
a: 只写,追加
a+: 读写,追加
返回值:成功返回文件指针 失败返回NULL
*/
FILE* fopen(const char* path, const char* mode);
#include <stdio.h>
/*
功能:关闭文件
参数:待关闭文件
返回值:成功返回0 失败返回EOF
*/
int fclose(FILE* fp);
第一组:将单个字符进行读写
#include <stdio.h>
/*
功能:读一个字符
参数:待读取文件指针
返回值:成功返回读取的字符 失败返回EOF
*/
int fgetc(FILE* stream);
/*
功能:写入一个字符
参数1:待写入字符
参数2:待写入目标文件的文件指针
返回值:成功返回写入的字符 失败返回EOF
*/
int fputc(int c, FILE* stream);
第二组:将多个字符进行读写(最多一行数据)
#include <sys/ioctl.h>
/*
功能:从文件读取最多一行数据
参数1:缓冲区指针
参数2:缓冲区大小
参数3:待读取文件指针
返回值:成功返回缓冲区指针 失败返回NULL
*/
char* fgets(char* s, int size, FILE* stream);
/*
功能:从文件写入最多一行数据
参数1:缓冲区指针
参数2:待写入文件指针
返回值:成功返回非负整数 失败返回EOF
*/
int fputs(const char* s, FILE* stream);
第三组:将若干数据块进行读写
#include <sys/ioctl.h>
/*
功能:从文件读取若干数据块
参数1:缓冲区指针
参数2:数据块大小
参数3:数据块个数
参数4:待读取文件指针
返回值:成功返回数据块个数==读取的数据块个数 失败返回值小于数据块个数
*/
size_t fread(void* ptr, size_t size, size_t nmemb, FILE* stream);
/*
功能:从文件写入若干数据块
参数1:缓冲区指针
参数2:数据块大小
参数3:数据块个数
参数4:待读取文件指针
返回值:成功返回数据块个数==读取的数据块个数 失败返回值小于数据块个数
*/
size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream);
目录检索
基本概念
Linux中的目录有区别于Windows中的文件夹。Windows中的文件夹就是“套娃”,文件夹里面的内容一定比文件夹本身空间小;而Linux中的目录就是变相的文件,没有大小层级关系,内部可以看作保存着其他文件的名称(地址)。
#include <sys/types.h>
#include <dirent.h>
/*
功能:打开目录获得目录指针
参数:待打开目录名
返回值:成功返回目录指针 失败返回NULL
*/
DIR* opendir(const char* name);
#include <dirent.h>
/*
功能:读取目录项
参数:待读取目录项的目录指针
返回值:成功返回目录项指针 失败返回NULL
*/
struct dirent* readdir(DIR* dir);
应用案例
int main(int argc, char* argv[])
{
DIR* dir = opendir("../XAYQ2407");
if(dir == NULL)
{
perror("opendir error");
return -1;
}
struct dirent* df = NULL;
while(1)
{
df = readdir(dir);
if(df == NULL)
{
break;
}
printf("%s\n", df->d_name);
}
return 0;
}