news 2026/6/9 21:13:38

FATFS学习笔记

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
FATFS学习笔记

声明

这个笔记是基于B站“李述铜聊嵌入式”老师的《FATFS文件系统详解系列之一:5小时快速入门嵌入式文件系统FATFS》课程的个人学习笔记。

1.1 什么是文件系统

1.为什么需要文件系统

对于一些较小的简单的数据,可以直接储存在MCU内部的Flash里,或者外挂一颗小的EEPROM(EEPROM 可以理解为一个容量很小但很“耐用”的存储器,非常适合用来保存那些需要频繁修改、断电后也不能丢失的少量数据)。如果数据量再大一些,可以外挂一颗大容量的SPI接口的Flash。

2.文件系统到底是什么

1.2 FAT文件系统简介

1.起源

2.储存设备一般结构

3.FAT文件系统结构

directory entry:它就像文件系统里的“通讯录”,用于记录文件名、文件大小、在存储设备上的位置、创建修改时间等信息,作用是帮助操作系统快速找到文件。像FATFS这类嵌入式文件系统,就是通过它来管理文件和目录的。

1.3 什么是FATFS

RTOS:RTOS 的全称是Real-Time Operating System,中文叫实时操作系统。可以把它理解成一个能同时处理多件事的“超级循环调度员”

平时写的while(1)大循环(裸机编程)就像一个人在做多件事:

  • 先看一眼按键有没有按下

  • 再去处理串口数据

  • 再去刷新屏幕

  • 再回去看按键……
    他是一件一件轮流做的,如果某件事卡住了(比如等待网络响应),后面的事也会被耽误。

而 RTOS 就像给每件事分配一个独立的小工人

  • 工人 A 专门负责按键

  • 工人 B 专门负责串口

  • 工人 C 专门负责语音播报

这些工人可以同时工作(看起来),而且重要的事可以优先处理(比如紧急停止按钮按下,立刻打断其他任务)。

RTOS 是一个让单片机能够“同时”执行多个任务的“操作系统内核”。它帮你管理任务的切换、优先级和通信。

2.1 挂载文件系统

作用:

FASFS使用前需进行挂载操作,才能对相应的文件和目录进行访问。

#include <stdio.h> #include "../fatfs/source/ff.h" //用路径的方式包含ff.h头文件 static FATFS disk1_fs; //定义一个FATFS类型的变量,作为磁盘0的文件系统对象 static FATFS disk2_fs; int main(void) { //挂载磁盘1,参数分别是文件系统对象、路径和选项,1为立即挂载文件系统 // fmount在此处的作用是将磁盘0与文件系统对象disk1_fs关联起来,使得后续对磁盘0的文件操作能够通过disk1_fs来进行管理和访问 // 0: -> disk1.vhd //FRESULT类型的变量res用于接收f_mount函数的返回值,判断挂载是否成功 FRESULT res = f_mount(&disk1_fs, "0:", 1); if (res_1 != FR_OK) { printf("mount disk1 failed.\n"); return -1; //如果挂载失败,输出错误信息并返回-1,结束程序 } res = f_mount(&disk2_fs, "1:", 1); if (res_2 != FR_OK) { printf("mount disk2 failed.\n"); return -1; } f_unmount("0:"); //卸载磁盘0,参数是路径,0:表示磁盘0 f_unmount("1:"); printf("hello, world\n"); return 0; }

2.2 打开与关闭文件系统

文件打开

文件关闭

#include <stdio.h> #include "../fatfs/source/ff.h" //用路径的方式包含ff.h头文件 static FATFS disk1_fs; //定义一个FATFS类型的变量,作为磁盘0的文件系统对象 static FATFS disk2_fs; int main(void) { //挂载磁盘1,参数分别是文件系统对象、路径和选项,1为立即挂载文件系统 // fmount在此处的作用是将磁盘0与文件系统对象disk1_fs关联起来,使得后续对磁盘0的文件操作能够通过disk1_fs来进行管理和访问 // 0: -> disk1.vhd //FRESULT类型的变量res用于接收f_mount函数的返回值,判断挂载是否成功 FRESULT res = f_mount(&disk1_fs, "0:", 1); if (res != FR_OK) { printf("mount disk1 failed.\n"); return -1; //如果挂载失败,输出错误信息并返回-1,结束程序 } res = f_mount(&disk2_fs, "1:", 1); if (res != FR_OK) { printf("mount disk2 failed.\n"); return -1; } //在FatFs文件系统中声明一个文件对象file,用于后续的文件操作,如打开、读取、写入等。 // FIL是FatFs库中定义的一个结构体类型,包含了文件的相关信息和状态。 //直接放在函数中占用字节较大,放在全局区占用字节较小,或用static修饰放在函数中占用字节较小 FIL file; res = f_open(&file, "0:/b.txt", FA_READ); //打开磁盘0根目录下的b.txt文件,FA_READ表示以只读方式打开文件,把文件的相关信息保存在file对象中 if (res != FR_OK) { printf("open file error.\n"); return -1; } f_close(&file); //关闭文件对象file,释放相关资源 f_unmount("0:"); //卸载磁盘1,参数是路径,0:表示磁盘0 f_unmount("1:"); printf("hello, world\n"); return 0; }
#include <stdio.h> #include "../fatfs/source/ff.h" //用路径的方式包含ff.h头文件 static FATFS disk1_fs; //定义一个FATFS类型的变量,作为磁盘0的文件系统对象 static FATFS disk2_fs; int main(void) { //挂载磁盘1,参数分别是文件系统对象、路径和选项,1为立即挂载文件系统 // fmount在此处的作用是将磁盘0与文件系统对象disk1_fs关联起来,使得后续对磁盘0的文件操作能够通过disk1_fs来进行管理和访问 // 0: -> disk1.vhd //FRESULT类型的变量res用于接收f_mount函数的返回值,判断挂载是否成功 FRESULT res = f_mount(&disk1_fs, "0:", 1); if (res != FR_OK) { printf("mount disk1 failed.\n"); return -1; //如果挂载失败,输出错误信息并返回-1,结束程序 } res = f_mount(&disk2_fs, "1:", 1); if (res != FR_OK) { printf("mount disk2 failed.\n"); return -1; } //在FatFs文件系统中声明一个文件对象file,用于后续的文件操作,如打开、读取、写入等。 // FIL是FatFs库中定义的一个结构体类型,包含了文件的相关信息和状态。 //直接放在函数中占用字节较大,放在全局区占用字节较小,或用static修饰放在函数中占用字节较小 FIL file; res = f_open(&file, "0:/b.txt", FA_OPEN_APPEND | FA_WRITE); //打开磁盘0根目录下的b.txt文件,参数分别是文件对象、路径和模式,FA_OPEN_APPEND表示以追加模式打开文件,如果文件不存在则创建,FA_WRITE表示以写入模式打开文件 if (res != FR_OK) { printf("open file error.\n"); return -1; } f_close(&file); //关闭文件对象file,释放相关资源 f_unmount("0:"); //卸载磁盘1,参数是路径,0:表示磁盘0 f_unmount("1:"); printf("hello, world\n"); return 0; }

2.3 读取和写入文件

读取文件

写入文件

#include <stdio.h> #include "../fatfs/source/ff.h" //用路径的方式包含ff.h头文件 static FATFS disk1_fs; //定义一个FATFS类型的变量,作为磁盘0的文件系统对象 static FATFS disk2_fs; int main(void) { //挂载磁盘1,参数分别是文件系统对象、路径和选项,1为立即挂载文件系统 // fmount在此处的作用是将磁盘0与文件系统对象disk1_fs关联起来,使得后续对磁盘0的文件操作能够通过disk1_fs来进行管理和访问 // 0: -> disk1.vhd //FRESULT类型的变量res用于接收f_mount函数的返回值,判断挂载是否成功 FRESULT res = f_mount(&disk1_fs, "0:", 1); if (res != FR_OK) { printf("mount disk1 failed.\n"); return -1; //如果挂载失败,输出错误信息并返回-1,结束程序 } res = f_mount(&disk2_fs, "1:", 1); if (res != FR_OK) { printf("mount disk2 failed.\n"); return -1; } //在FatFs文件系统中声明一个文件对象file,用于后续的文件操作,如打开、读取、写入等。 // FIL是FatFs库中定义的一个结构体类型,包含了文件的相关信息和状态。 //直接放在函数中占用字节较大,放在全局区占用字节较小,或用static修饰放在函数中占用字节较小 FIL file; res = f_open(&file, "0:/rtos/os_sem.c", FA_READ); //打开磁盘0根目录下的rtos目录中的os_sem.c文件,FA_READ表示以只读方式打开文件 if (res != FR_OK) { printf("open file error.\n"); return -1; } while (1) { static char read_buf[1024]; //定义一个字符数组read_buf,用于存储从文件中读取的数据 UINT read_size; //定义一个UINT类型的变量read_size,用于存储实际读取的字节数 res = f_read(&file, read_buf, sizeof(read_buf) - 1, &read_size); //从文件对象file中读取数据到read_buf中,读取的最大字节数为sizeof(read_buf) - 1,实际读取的字节数存储在read_size中 if (res != FR_OK) { printf("\n read error.\n"); break; } //read_buf的最后一项改成\0, //read_size 是已读取的字节数,它指向缓冲区中第一个未占用的位置。所以 read_buf[read_size] 就是紧跟在有效数据后面的位置,正好用来放 '\0'。不需要 + 1,因为 read_size 已经正确表示了结束符的索引。 read_buf[read_size] = '\0'; printf("%s",read_buf); //判断是否读完,读完跳出程序 if (read_size < sizeof(read_buf) - 1) { printf("\n---read comp---/n"); break; } } f_close(&file); //关闭文件对象file,释放相关资源 f_unmount("0:"); //卸载磁盘1,参数是路径,0:表示磁盘0 f_unmount("1:"); printf("hello, world\n"); return 0; }

文件写入刷新

#include <stdio.h> #include "../fatfs/source/ff.h" //用路径的方式包含ff.h头文件 static FATFS disk1_fs; //定义一个FATFS类型的变量,作为磁盘0的文件系统对象 static FATFS disk2_fs; int main(void) { //挂载磁盘1,参数分别是文件系统对象、路径和选项,1为立即挂载文件系统 // fmount在此处的作用是将磁盘0与文件系统对象disk1_fs关联起来,使得后续对磁盘0的文件操作能够通过disk1_fs来进行管理和访问 // 0: -> disk1.vhd //FRESULT类型的变量res用于接收f_mount函数的返回值,判断挂载是否成功 FRESULT res = f_mount(&disk1_fs, "0:", 1); if (res != FR_OK) { printf("mount disk1 failed.\n"); return -1; //如果挂载失败,输出错误信息并返回-1,结束程序 } res = f_mount(&disk2_fs, "1:", 1); if (res != FR_OK) { printf("mount disk2 failed.\n"); return -1; } //在FatFs文件系统中声明一个文件对象file,用于后续的文件操作,如打开、读取、写入等。 // FIL是FatFs库中定义的一个结构体类型,包含了文件的相关信息和状态。 //直接放在函数中占用字节较大,放在全局区占用字节较小,或用static修饰放在函数中占用字节较小 FIL file; res = f_open(&file, "0:/sync.txt", FA_WRITE | FA_CREATE_ALWAYS); //打开磁盘0根目录下的sync.txt文件,使用写入模式,如果文件不存在则创建,如果存在则覆盖 if (res != FR_OK) { printf("open file error.\n"); return -1; } for (int i = 0; i < 10000; i++) { static char write_buf[100]; //定义一个静态字符数组writr_buf,用于存储要写入文件的数据 int len = sprintf(write_buf, "%d:%s\n", i, "12345678"); //使用sprintf函数将格式化的字符串写入write_buf中,格式为"i:12345678\n",其中i是循环变量的值,len是写入字符串的长度 UINT write_size; //实际写入的长度 res = f_write(&file, write_buf, len, &write_size); //调用f_write函数将write_buf中的数据写入文件,参数分别是文件对象、数据缓冲区、要写入的字节数和实际写入的字节数 if (res != FR_OK) //判断写入是否成功,如果返回值不是FR_OK,则输出错误信息并跳出循环 { printf("write file error.\n"); break; } if (i == 5000) { f_sync(&file); //调用f_sync函数将文件对象file的缓冲区数据强制写入磁盘,确保数据的持久化 *(unsigned char*)0 = 0x1234; //故意触发一个访问违规的错误,模拟程序崩溃的情况 } } f_close(&file); //关闭文件对象file,释放相关资源 f_unmount("0:"); //卸载磁盘1,参数是路径,0:表示磁盘0 f_unmount("1:"); printf("hello, world\n"); return 0; }

文件写入示例代码

#include <stdio.h> #include "../fatfs/source/ff.h" //用路径的方式包含ff.h头文件 static FATFS disk1_fs; //定义一个FATFS类型的变量,作为磁盘0的文件系统对象 static FATFS disk2_fs; int main(void) { //挂载磁盘1,参数分别是文件系统对象、路径和选项,1为立即挂载文件系统 // fmount在此处的作用是将磁盘0与文件系统对象disk1_fs关联起来,使得后续对磁盘0的文件操作能够通过disk1_fs来进行管理和访问 // 0: -> disk1.vhd //FRESULT类型的变量res用于接收f_mount函数的返回值,判断挂载是否成功 FRESULT res = f_mount(&disk1_fs, "0:", 1); if (res != FR_OK) { printf("mount disk1 failed.\n"); return -1; //如果挂载失败,输出错误信息并返回-1,结束程序 } res = f_mount(&disk2_fs, "1:", 1); if (res != FR_OK) { printf("mount disk2 failed.\n"); return -1; } //在FatFs文件系统中声明一个文件对象file,用于后续的文件操作,如打开、读取、写入等。 // FIL是FatFs库中定义的一个结构体类型,包含了文件的相关信息和状态。 //直接放在函数中占用字节较大,放在全局区占用字节较小,或用static修饰放在函数中占用字节较小 FIL file; res = f_open(&file, "0:/sync.txt", FA_WRITE | FA_CREATE_ALWAYS); //打开磁盘0根目录下的sync.txt文件,使用写入模式,如果文件不存在则创建,如果存在则覆盖 if (res != FR_OK) { printf("open file error.\n"); return -1; } for (int i = 0; i < 10000; i++) { static char write_buf[100]; //定义一个静态字符数组writr_buf,用于存储要写入文件的数据 int len = sprintf(write_buf, "%d:%s\n", i, "12345678"); //使用sprintf函数将格式化的字符串写入write_buf中,格式为"i:12345678\n",其中i是循环变量的值,len是写入字符串的长度 UINT write_size; //实际写入的长度 res = f_write(&file, write_buf, len, &write_size); //调用f_write函数将write_buf中的数据写入文件,参数分别是文件对象、数据缓冲区、要写入的字节数和实际写入的字节数 if (res != FR_OK) //判断写入是否成功,如果返回值不是FR_OK,则输出错误信息并跳出循环 { printf("write file error.\n"); break; } } f_close(&file); //关闭文件对象file,释放相关资源 f_unmount("0:"); //卸载磁盘1,参数是路径,0:表示磁盘0 f_unmount("1:"); printf("hello, world\n"); return 0; }

2.4 以字符串方式读文件

#include <stdio.h> #include "../fatfs/source/ff.h" //用路径的方式包含ff.h头文件 static FATFS disk1_fs; //定义一个FATFS类型的变量,作为磁盘0的文件系统对象 static FATFS disk2_fs; int main(void) { //挂载磁盘1,参数分别是文件系统对象、路径和选项,1为立即挂载文件系统 // fmount在此处的作用是将磁盘0与文件系统对象disk1_fs关联起来,使得后续对磁盘0的文件操作能够通过disk1_fs来进行管理和访问 // 0: -> disk1.vhd //FRESULT类型的变量res用于接收f_mount函数的返回值,判断挂载是否成功 FRESULT res = f_mount(&disk1_fs, "0:", 1); if (res != FR_OK) { printf("mount disk1 failed.\n"); return -1; //如果挂载失败,输出错误信息并返回-1,结束程序 } res = f_mount(&disk2_fs, "1:", 1); if (res != FR_OK) { printf("mount disk2 failed.\n"); return -1; } //在FatFs文件系统中声明一个文件对象file,用于后续的文件操作,如打开、读取、写入等。 // FIL是FatFs库中定义的一个结构体类型,包含了文件的相关信息和状态。 //直接放在函数中占用字节较大,放在全局区占用字节较小,或用static修饰放在函数中占用字节较小 FIL file; res = f_open(&file, "0:/rtos/os_sem.c", FA_READ); //打开磁盘0上的文件"rtos/os_sem.c",以只读模式打开,参数分别是文件对象、文件路径和打开模式 if (res != FR_OK) { printf("open file error.\n"); return -1; } while (1) { static TCHAR read_buf[100]; //定义一个静态字符数组read_buf,用于存储从文件中读取的数据,大小为100字节 TCHAR *str = f_gets(read_buf, 100, &file); //从文件对象file中读取一行文本数据,存储到read_buf中,参数分别是读取缓冲区、缓冲区大小和文件对象 if (str == NULL) //如果读取失败或到达文件末尾,f_gets函数会返回NULL,此时跳出循环 { break; } printf("%s", str); //输出读取到的文本数据 } f_close(&file); //关闭文件对象file,释放相关资源 f_unmount("0:"); //卸载磁盘1,参数是路径,0:表示磁盘0 f_unmount("1:"); printf("hello, world\n"); return 0; }

2.5 以字符串方式写文件

#include <stdio.h> #include "../fatfs/source/ff.h" //用路径的方式包含ff.h头文件 static FATFS disk1_fs; //定义一个FATFS类型的变量,作为磁盘0的文件系统对象 static FATFS disk2_fs; int main(void) { //挂载磁盘1,参数分别是文件系统对象、路径和选项,1为立即挂载文件系统 // fmount在此处的作用是将磁盘0与文件系统对象disk1_fs关联起来,使得后续对磁盘0的文件操作能够通过disk1_fs来进行管理和访问 // 0: -> disk1.vhd //FRESULT类型的变量res用于接收f_mount函数的返回值,判断挂载是否成功 FRESULT res = f_mount(&disk1_fs, "0:", 1); if (res != FR_OK) { printf("mount disk1 failed.\n"); return -1; //如果挂载失败,输出错误信息并返回-1,结束程序 } res = f_mount(&disk2_fs, "1:", 1); if (res != FR_OK) { printf("mount disk2 failed.\n"); return -1; } //在FatFs文件系统中声明一个文件对象file,用于后续的文件操作,如打开、读取、写入等。 // FIL是FatFs库中定义的一个结构体类型,包含了文件的相关信息和状态。 //直接放在函数中占用字节较大,放在全局区占用字节较小,或用static修饰放在函数中占用字节较小 FIL file; res = f_open(&file, "0:/rtos/os_sem.c", FA_WRITE | FA_OPEN_APPEND); //打开磁盘0目录下的os_sem.c文件,参数分别是文件对象、文件路径和打开模式,FA_WRITE表示以写入模式打开文件,FA_OPEN_APPEND表示如果文件存在则在末尾追加内容 if (res != FR_OK) { printf("open file error.\n"); return -1; } f_puts("rtos is running\n", &file); //向文件中写入字符串"rtos is running",参数分别是要写入的字符串和文件对象 f_putc('o', &file); //向文件中写入一个字符'o',参数分别是要写入的字符和文件对象 f_putc('k', &file); f_close(&file); //关闭文件对象file,释放相关资源 f_unmount("0:"); //卸载磁盘1,参数是路径,0:表示磁盘0 f_unmount("1:"); printf("hello, world\n"); return 0; }

2.6 文件读写定位

#include <stdio.h> #include "../fatfs/source/ff.h" //用路径的方式包含ff.h头文件 static FATFS disk1_fs; //定义一个FATFS类型的变量,作为磁盘0的文件系统对象 static FATFS disk2_fs; int main(void) { //挂载磁盘1,参数分别是文件系统对象、路径和选项,1为立即挂载文件系统 // fmount在此处的作用是将磁盘0与文件系统对象disk1_fs关联起来,使得后续对磁盘0的文件操作能够通过disk1_fs来进行管理和访问 // 0: -> disk1.vhd //FRESULT类型的变量res用于接收f_mount函数的返回值,判断挂载是否成功 FRESULT res = f_mount(&disk1_fs, "0:", 1); if (res != FR_OK) { printf("mount disk1 failed.\n"); return -1; //如果挂载失败,输出错误信息并返回-1,结束程序 } res = f_mount(&disk2_fs, "1:", 1); if (res != FR_OK) { printf("mount disk2 failed.\n"); return -1; } //在FatFs文件系统中声明一个文件对象file,用于后续的文件操作,如打开、读取、写入等。 // FIL是FatFs库中定义的一个结构体类型,包含了文件的相关信息和状态。 //直接放在函数中占用字节较大,放在全局区占用字节较小,或用static修饰放在函数中占用字节较小 FIL file; res = f_open(&file, "0:/data.bin", FA_READ); //打开磁盘0目录下的data.bin文件,参数分别是文件对象、文件路径和打开模式,FA_READ表示以只读模式打开文件 if (res != FR_OK) { printf("open file error.\n"); return -1; } static char read_buf[100]; //定义一个静态字符数组read_buf,大小为100字节,用于存储从文件中读取的数据 UINT read_size; //定义一个UINT类型的变量read_size,用于存储实际读取的字节数 //从第32个字节开始读取100个字节的数据到read_buf中,参数分别是文件对象、读取缓冲区、要读取的字节数和实际读取的字节数 f_lseek(&file, 32); //将文件指针移动到第32个字节的位置,准备从该位置开始读取数据 f_read(&file, read_buf, sizeof(read_buf), &read_size); //从文件中读取数据到read_buf中,实际读取的字节数存储在read_size变量中 f_lseek(&file, 100); f_read(&file, read_buf, sizeof(read_buf), &read_size); f_rewind(&file); //将文件指针重新定位到文件的开头位置,准备从文件的开始位置进行读取或写入操作 f_read(&file, read_buf, sizeof(read_buf), &read_size); f_close(&file); //关闭文件对象file,释放相关资源 f_unmount("0:"); //卸载磁盘1,参数是路径,0:表示磁盘0 f_unmount("1:"); printf("hello, world\n"); return 0; }

2.7 调整写位置进行扩容

#include <stdio.h> #include "../fatfs/source/ff.h" //用路径的方式包含ff.h头文件 static FATFS disk1_fs; //定义一个FATFS类型的变量,作为磁盘0的文件系统对象 static FATFS disk2_fs; int main(void) { //挂载磁盘1,参数分别是文件系统对象、路径和选项,1为立即挂载文件系统 // fmount在此处的作用是将磁盘0与文件系统对象disk1_fs关联起来,使得后续对磁盘0的文件操作能够通过disk1_fs来进行管理和访问 // 0: -> disk1.vhd //FRESULT类型的变量res用于接收f_mount函数的返回值,判断挂载是否成功 FRESULT res = f_mount(&disk1_fs, "0:", 1); if (res != FR_OK) { printf("mount disk1 failed.\n"); return -1; //如果挂载失败,输出错误信息并返回-1,结束程序 } res = f_mount(&disk2_fs, "1:", 1); if (res != FR_OK) { printf("mount disk2 failed.\n"); return -1; } //在FatFs文件系统中声明一个文件对象file,用于后续的文件操作,如打开、读取、写入等。 // FIL是FatFs库中定义的一个结构体类型,包含了文件的相关信息和状态。 //直接放在函数中占用字节较大,放在全局区占用字节较小,或用static修饰放在函数中占用字节较小 FIL file; res = f_open(&file, "0:/data1.bin", FA_WRITE | FA_CREATE_ALWAYS); //打开磁盘0目录下的data1.bin文件,参数分别是文件对象、文件路径和打开模式,FA_WRITE表示以写入模式打开文件,FA_CREATE_ALWAYS表示如果文件已存在则覆盖它,如果不存在则创建一个新文件 if (res != FR_OK) { printf("open file error.\n"); return -1; } #if 0 static char read_buf[100]; //定义一个静态字符数组read_buf,大小为100字节,用于存储从文件中读取的数据 UINT read_size; //定义一个UINT类型的变量read_size,用于存储实际读取的字节数 //从第32个字节开始读取100个字节的数据到read_buf中,参数分别是文件对象、读取缓冲区、要读取的字节数和实际读取的字节数 f_lseek(&file, 32); //将文件指针移动到第32个字节的位置,准备从该位置开始读取数据 f_read(&file, read_buf, sizeof(read_buf), &read_size); //从文件中读取数据到read_buf中,实际读取的字节数存储在read_size变量中 f_lseek(&file, 100); f_read(&file, read_buf, sizeof(read_buf), &read_size); f_rewind(&file); //将文件指针重新定位到文件的开头位置,准备从文件的开始位置进行读取或写入操作 f_read(&file, read_buf, sizeof(read_buf), &read_size); #endif f_lseek(&file, 200); //将文件指针移动到第200个字节的位置,准备从该位置开始进行写入操作 f_close(&file); //关闭文件对象file,释放相关资源 f_unmount("0:"); //卸载磁盘1,参数是路径,0:表示磁盘0 f_unmount("1:"); printf("hello, world\n"); return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/9 21:12:10

直播间快递丢失破损:电商链条末端责任真空

“我在直播间下单买了护肤品&#xff0c;收到快递发现瓶子碎了。找主播&#xff0c;主播让找发货方&#xff1b;找品牌&#xff0c;品牌说物流是第三方&#xff1b;找物流&#xff0c;物流说包装没问题。最后我成了‘皮球’&#xff0c;被踢来踢去。”这个场景&#xff0c;每天…

作者头像 李华
网站建设 2026/6/9 21:11:23

IDM永久激活终极指南:5种简单方法告别30天试用期限制

IDM永久激活终极指南&#xff1a;5种简单方法告别30天试用期限制 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script 还在为Internet Download Manager的30天试用期而…

作者头像 李华
网站建设 2026/6/9 21:08:07

i.MX 6SoloX引脚配置与电源管理设计实战指南

1. 项目概述与核心价值在嵌入式硬件设计领域&#xff0c;尤其是面对像NXP i.MX 6SoloX这类功能丰富的工业级应用处理器时&#xff0c;引脚配置与电源管理往往是决定项目成败的第一道关卡。这不仅仅是把芯片焊到板子上、接上电源那么简单。它更像是在一个极其有限的物理空间&…

作者头像 李华
网站建设 2026/6/9 21:08:07

Spring Boot 3.x虚拟线程与WebFlux响应式模型:并发范式的深度对比

Spring Boot 3.x虚拟线程与WebFlux响应式模型&#xff1a;并发范式的深度对比一、并发模型的选择困境&#xff1a;虚拟线程还是响应式&#xff1f; Spring Boot 3.x 引入了对 Java 21 虚拟线程&#xff08;Virtual Threads&#xff09;的一等支持&#xff0c;这给 Java 后端开发…

作者头像 李华
网站建设 2026/6/9 21:06:38

护网必学日志分析

最近在准备护网面试&#xff0c;但是看到csdn上面很多日志分析文章都收费&#xff0c;当然也有不收费的方法&#xff0c;但是直接看不是方便点&#xff1f;我大概搜集一下共同的知识点目录&#xff0c;整理一篇笔记供参考 一、 协议基础&#xff1a;HTTP 请求字段 一个完整的 H…

作者头像 李华