既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
>函数:
打开文件:
open:
/*调用时需要添加的头文件*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/*
*函数名:open
*函数功能:打开一个文件
*函数参数:
* const char *pathname:带路径的文件名
* int flags:打开方式
* O_RDONLY:只读
* O_WRONLY:只写
* O_RDWR:可读可写
*函数返回值:int:成功返回一个被打开文件的文件描述符,失败返回一个负数
*/
int open(const char *pathname, int flags);
创建文件:
open:
/*
*函数名:open
*函数功能:打开文件,如果文件不存在,可以创建(一般用于创建文件)
*函数参数:
* const char *pathname:带路径的文件名
* int flags:打开方式
* O_RDONLY:只读
* O_WRONLY:只写
* O_RDWR:可读可写
* O_CREAT:创建时必须加
* mode_t mode:三个八进制的数 0664
*函数返回值:成功返回一个被打开文件的文件描述符,失败返回一个负数
*/
int open(const char *pathname, int flags, mode_t mode);
不常用的flags:
O_APPEND 如果文件存在,则以追加方式打开
O_TRUNC 如果文件存在,则清空
O_NOCTTY 如果路径名指向终端设备,不要把这个设备用作控制终端。
O_NONBLOCK 如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/O设置为非阻塞模式(nonblocking mode)
以下三个常量同样是选用的,它们用于同步输入输出
O_DSYNC 等待物理 I/O 结束后再 write。在不影响读取新写入的数据的前提下,不等待文件属性更新。
O_RSYNC read 等待所有写入同一区域的写操作完成后再进行
O_SYNC 等待物理 I/O 结束后再 write,包括更新文件属性的 I/O
标准IO中 r r+ w w+ a a+ 分别对应那些 O_XXX 的组合
标准IO 文件IO
r O_RDONLY
r+ O_RDWR
w O_WRONLY | O_CREAT | O_TRUNC
w+ O_RDWR | O_CREAT | O_TRUNC
a O_WRONLY | O_CREAT | O_APPEND
a+ O_RDWR | O_CREAT | O_APPEND
open时,文件权限的问题:
我们在使用0777权限创建文件时,创建出的文件权限是0775,这是为什么?
因为dest_mode = open_mode & (~umask)
umask:linux操作系统默认为0002
故:
open_mode:0777
umask:0002
111 111 111
000 000 010 按位取反 111 111 101
按位与的结果:111 111 101 ----------->0775
读文件:
read:
/*需要包含的头文件*/
#include <unistd.h>
/*
*函数名:read
*函数功能:从一个文件描述符读取数据
*函数参数:
* int fd:被读的文件的文件描述符
* void *buf:buf是用来存储读取数据存储的内存空间的首地址
* size_t count:表示的是想要读取的字节数
*函数返回值:int:成功返回读到的字节数,失败返回-1,如果读指针本身就在文件末尾则读不到数据,返回0
*/
ssize_t read(int fd, void *buf, size_t count);
读文件示例:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char \*argv[])
{
if(argc != 2)
{
puts("Usage:./a.out filename");
return -1;
}
//open file
int fd = -1;
fd = open(argv[1], O_RDONLY);
if(fd < 0)
{
puts("open file error.");
return -1;
}
//read file
char buf[11] = {0};
int ret = read(fd,buf,sizeof(buf));
if(ret > 0)
{
puts(buf);
printf("ret:%d\n",ret);
}
//close file
close(fd);
return 0;
}
写文件:
write:
/*需要包含的头文件*/
#include <unistd.h>
/*
*函数名:write
*函数功能:往一个文件描述符写入数据
*函数参数:
* int fd:被写入的文件的文件描述符
* void *buf:buf是用来存储写入数据存储的内存空间的首地址
* size_t count:表示的是想要写入的字节数
*函数返回值:int:成功返回写入的字节数,失败返回-1
*/
ssize_t write(int fd, const void *buf, size_t count);
关闭文件:
close:
/*需要包含的头文件*/
#include <unistd.h>
/*
*函数名:close
*函数功能:关闭一个文件描述符
*函数参数:
* int fd:被关闭/想要关闭的文件的文件描述符
*函数返回值:int:成功返回0,失败返回-1
*/
int close(int fd);
写文件示例:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main()
{
//create file
int fd = -1;
fd = open("mytest",O_WRONLY | O_CREAT, 0664);
if(fd < 0)
{
puts("creat file error.");
return -1;
}
//write buf to file
char buf[] = "Tom and Jerry\n";
write(fd,buf,strlen(buf));
//close file
close(fd);
return 0;
}
文件重定位:
lseek:
/*需要添加的头文件*/
#include <sys/types.h>
#include <unistd.h>
/*
*函数名:lseek
*函数功能:文件读写指针的重定位
*函数参数:
* int fd:文件描述符
* off_t offset:偏移量
* int whence:基准
*函数返回值:
* off_t:成功返回基于当前位置移动的字节数
*/
off_t lseek(int fd, off_t offset, int whence);
whence:
SEEK_SET(文件开头)
The offset is set to offset bytes.
SEEK_CUR(当前位置)
The offset is set to its current location plus offset bytes.
SEEK_END(文件末尾)
The offset is set to the size of the file plus offset bytes.
课堂练习:
1.求文件长度
使用文件IO实现
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char \*argv[])
{
if(argc != 2)
{
puts("Usage:./a.out filename");
return -1;
}
int fd = open(argv[1],O_RDONLY);
if(fd < 0)
{
puts("open file error.");
return -1;
}
int ret = lseek(fd,0,SEEK\_END);
printf("ret:%d\n",ret);
close(fd);
return 0;
}
库:
->什么是库
库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。
->什么时候使用库
1.工程中部分源代码闭源时使用库
2.版本升级时使用
->库的分类
静态库:在程序编译时的链接阶段将目标文件.o和库文件.a链接生成可执行文件。将这个过程中的.a称之为静态库
以.a/.lib为后缀
动态库:在程序运行时,将加载到内存中的.so代码链接到可执行文件中,执行库中的代码段。将这个过程中的.so称之为动态库。
以.so/.dll为后缀
动态库也称之为共享库
系统 静态库 动态库
Linux下的库 xxx.a xxx.so
Windows下的库 xxx.lib xxx.dll
->库的制作
静态库的制作:
1.将接口文件,编译,汇编生成.o目标文件
gcc -c xxx.c
2.使用ar命令,将.o目标文件做成静态库
ar -crv libxxx.a xxx.o
动态库的制作:
创建动态库(.so)
编写代码
(老版本的编译器是可以的)
将代表生成目标文件,此时要加上编译器选项-fPIC
-fPIC创建与地址无关的编译程序(pic, position independent code),是为了能够在多个应用程序间共享。
gcc -fPIC -c mysort.c
然后生成动态库,此时要加链接器选项-shared
gcc -shared -o libmysort.so mysort.o
-shared指定生成动态链接库。
新版本的编译器建议使用如下方法:
gcc -fPIC -shared -c xxxx.c -o libxxx.so
注意:建议使用新版的生成方法,新版本向下兼容,旧版本不向上兼容
->库的链接
静态库的链接:
![img](https://img-blog.csdnimg.cn/img_convert/616e6f28e064df8edd89285c44f92d97.png)
![img](https://img-blog.csdnimg.cn/img_convert/3a5fb1180b2ee98adc2dfcc3e362090d.png)
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**
**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**
(img-nY2st8HI-1715803187643)]
[外链图片转存中...(img-5Jgctie5-1715803187643)]
**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**
**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**
**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**
**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**