STM32进阶笔记——FATFS文件系统(下)

  本专栏争取每周三更新直到更新完成,期待大家的订阅关注,欢迎互相学习交流。

  本文需要一些SD卡和内存管理等前置知识,后续文章会介绍,这里先介绍一下FATFS文件系统。关于FATFS的文章分为上下两篇,上篇主要介绍什么是FAT文件系统以及FATFS的移植,下篇主要介绍FATFS的一些API函数并给出一些简单的应用示例。

文章封面

目录

  • 一、结构体介绍
    • 1.1 文件对象结构体
    • 1.2 目录对象结构体
    • 1.3 文件信息结构体
  • 二、文件操作函数
    • 2.1 f_open函数
    • 2.2 f_close函数
    • 2.3 f_read函数
    • 2.4 f_write函数
    • 2.5 f_size获取文件大小
  • 三、目录操作函数
    • 3.1 f_opendir函数
    • 3.2 f_closedir函数
    • 3.3 f_readdir函数
  • 四、文件/目录管理函数
    • 4.1 f_unlink函数
    • 4.2 f_rename函数
    • 4.3 f_mkdir函数
  • 五、示例程序
    • 5.1 文件操作函数使用示例
    • 5.2 目录操作函数使用示例

一、结构体介绍

  在开始正式介绍FATFS的API函数之前,我们先来看几个关键的结构体,主要是简单了解一下其中的内容。

1.1 文件对象结构体

/* File object structure (FIL) */typedef struct {FATFS*	fs;				/* Pointer to the related file system object (**do not change order**) */WORD	id;				/* Owner file system mount ID (**do not change order**) */BYTE	flag;			/* Status flags */BYTE	err;			/* Abort flag (error code) */DWORD	fptr;			/* File read/write pointer (Zeroed on file open) */DWORD	fsize;			/* File size */DWORD	sclust;			/* File start cluster (0:no cluster chain, always 0 when fsize is 0) */DWORD	clust;			/* Current cluster of fpter (not valid when fprt is 0) */DWORD	dsect;			/* Sector number appearing in buf[] (0:invalid) */
#if !_FS_READONLYDWORD	dir_sect;		/* Sector number containing the directory entry */BYTE*	dir_ptr;		/* Pointer to the directory entry in the win[] */
#endif
#if _USE_FASTSEEKDWORD*	cltbl;			/* Pointer to the cluster link map table (Nulled on file open) */
#endif
#if _FS_LOCKUINT	lockid;			/* File lock ID origin from 1 (index of file semaphore table Files[]) */
#endif
#if !_FS_TINYBYTE	buf[_MAX_SS];	/* File private data read/write window */
#endif
} FIL;

1.2 目录对象结构体

/* Directory object structure (DIR) */typedef struct {FATFS*	fs;				/* Pointer to the owner file system object (**do not change order**) */WORD	id;				/* Owner file system mount ID (**do not change order**) */WORD	index;			/* Current read/write index number */DWORD	sclust;			/* Table start cluster (0:Root dir) */DWORD	clust;			/* Current cluster */DWORD	sect;			/* Current sector */BYTE*	dir;			/* Pointer to the current SFN entry in the win[] */BYTE*	fn;				/* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
#if _FS_LOCKUINT	lockid;			/* File lock ID (index of file semaphore table Files[]) */
#endif
#if _USE_LFNWCHAR*	lfn;			/* Pointer to the LFN working buffer */WORD	lfn_idx;		/* Last matched LFN index number (0xFFFF:No LFN) */
#endif
#if _USE_FINDconst TCHAR*	pat;	/* Pointer to the name matching pattern */
#endif
} DIR;

1.3 文件信息结构体

/* File information structure (FILINFO) */typedef struct {DWORD	fsize;			/* File size */WORD	fdate;			/* Last modified date */WORD	ftime;			/* Last modified time */BYTE	fattrib;		/* Attribute */TCHAR	fname[13];		/* Short file name (8.3 format) */
#if _USE_LFNTCHAR*	lfname;			/* Pointer to the LFN buffer */UINT 	lfsize;			/* Size of LFN buffer in TCHAR */
#endif
} FILINFO;

二、文件操作函数

2.1 f_open函数

  • 函数功能:打开或者创建一个文件。
  • 函数原型:FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode);
  • 输入参数:*fp:指向一个空白文件对象的结构体指针;
    *path:文件名指针;
    mode:模式标志,共有以下几种模式:
模式含义
FA_READ指定对对象的读访问权限。可以从文件中读取数据。
FA_WRITE指定对对象的写访问。数据可以写入文件。结合 FA _ READ 进行读写访问。
FA_OPEN_EXISTING打开文件。如果文件不存在,函数将失败 (默认值)。
FA_OPEN_ALWAYS如果文件存在,则打开该文件;如果没有,将创建一个新文件。
FA_CREATE_NEW创建一个新文件。如果文件存在,函数将失败。
FA_CREATE_ALWAYS创建一个新文件。如果该文件存在,它将被截断并覆盖。

  当 _ FS _ READONLY = = 1时(只读模式),模式标志 FA _ WRITE、 FA _ CREATE _ ALWAYS、 FA _ CREATE _ NEW 和 FA _ OPEN _ ALWAYS 不可用。

  • 返回值:返回值是一个结构体,这里在每一个返回值后面给出了中文描述,仅供参考。
typedef enum {FR_OK = 0,				/* (0) 成功*/FR_DISK_ERR,			/* (1) 低级磁盘 I/O 层发生了一个硬错误 */FR_INT_ERR,				/* (2) 断言失败 */FR_NOT_READY,			/* (3) 物理驱动无法工作 */FR_NO_FILE,				/* (4) 无法找到文件 */FR_NO_PATH,				/* (5) 无法找到路径 */FR_INVALID_NAME,		/* (6) 路径名格式无效 */FR_DENIED,				/* (7) 由于禁止访问或目录已满而拒绝访问 */FR_EXIST,				/* (8) 由于禁止访问而拒绝访问 */FR_INVALID_OBJECT,		/* (9) 文件/目录对象无效 */FR_WRITE_PROTECTED,		/* (10) 物理驱动器受写保护 */FR_INVALID_DRIVE,		/* (11) 逻辑驱动器号无效 */FR_NOT_ENABLED,			/* (12) 卷没有工作区 */FR_NO_FILESYSTEM,		/* (13) 没有有效的FAT卷 */FR_MKFS_ABORTED,		/* (14) 由于任何参数错误,f _ mkfs ()中止 */FR_TIMEOUT,				/* (15) 无法获得在规定期限内访问卷的授权 */FR_LOCKED,				/* (16) 根据文件共享策略拒绝该操作 */FR_NOT_ENOUGH_CORE,		/* (17) 无法分配 LFN工作缓冲区 */FR_TOO_MANY_OPEN_FILES,	/* (18) 打开的文件数 > _ FS _ SHARE */FR_INVALID_PARAMETER	/* (19) 给定的参数无效 */
} FRESULT;
  • 注意事项:在使用任何文件函数之前,必须使用 f _ mount 函数将工作区(文件系统对象)注册到逻辑驱动器(f_mount 函数后续会介绍)。除 f _ fdisk 函数之外的所有 API 函数都可以在此过程之后工作。打开的文件必须在断电、删除媒体或重新挂载之前关闭,否则文件可能会被折叠。若要关闭打开的文件,请使用 f _ close 函数。禁止复制打开任何写模式标志的文件。。

2.2 f_close函数

  • 函数功能:关闭一个打开的文件。
  • 函数原型:FRESULT f_close (FIL* fp);
  • 输入参数:*fp:指向要关闭的打开文件对象结构的指针。
  • 返回值:包含在FRESULT结构体,不再详细介绍。
  • 注意事项:如果任何数据已经写入文件,文件的缓存信息将被写回卷。函数成功执行后,file 对象不再有效,可以将其丢弃。

2.3 f_read函数

  • 函数功能:从一个文件中读取数据。
  • 函数原型:FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br);
  • 输入参数:*fp:指向打开文件对象的指针;
    *buff:指向存储读取数据的数组指针;
    btr:在 UINT 类型范围内要读取的字节数;
    *br:指向 UINT 变量的指针,以返回读取的字节数。无论结果如何,该值在函数调用后始终有效;
  • 返回值:包含在FRESULT结构体,不再详细介绍。
  • 注意事项:文件对象的文件读/写指针提高了读取的字节数。函数完成后,应该检查 * br 以检测文件的结尾。如果 * br 小于 btr,则表示在读操作期间读/写指针到达文件末尾。

2.4 f_write函数

  • 函数功能:往文件里写入数据。
  • 函数原型:FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw);
  • 输入参数:*fp:指向打开文件对象的指针;
    *buff:指向要写入的数据的指针;
    btw:指定要在 UINT 类型范围内写入的字节数;
    *bw:指向 UINT 变量的指针,以返回写入的字节数;
  • 返回值:包含在FRESULT结构体,不再详细介绍。
  • 注意事项:函数完成后,应该检查 * bw 以检测磁盘是否已满。如果 * bw 小于 btw,则表示在写操作期间卷已满。该函数可以在卷满或接近满时执行。

  经测试发现,写完成后必须关闭文件才能保存写的数据,如果写完成后不关闭文件直接读取,新写入的内容不会被读取出来。

2.5 f_size获取文件大小

  f_size 函数获取文件的大小,返回文件的大小(以字节为单位)。它是作为宏实现的,只需要输入一个指向打开的文件对象结构的指针即可,使用比较简单,这里之所以单独介绍这个函数,是因为我们后续在使用SD卡读取文件时,很多时候需要先知道文件大小,然后开辟合适的空间来存储读取出来的文件内容。f_size函数的定义如下

#define f_size(fp) ((fp)->fsize)

三、目录操作函数

3.1 f_opendir函数

  • 函数功能:打开一个目录(文件夹)。
  • 函数原型:FRESULT f_opendir (DIR* dp, const TCHAR* path);
  • 输入参数:*dp:指向空白目录对象的指针,以创建新的目录对象;
    *path:指向指定要打开的目录名称的空终止字符串的指针;
  • 返回值:包含在FRESULT结构体,不再详细介绍。
  • 注意事项:当_FS_MINIMIZE <= 1时可用。

  f_opendir函数是打开一个已存在的目录,并为后续的调用创建一个目录对象。该目录对象结构可以在任何时候不经任何步骤而被丢弃。

3.2 f_closedir函数

  • 函数功能:关闭一个打开的目录。
  • 函数原型:FRESULT f_closedir (DIR* dp);
  • 输入参数:指向要关闭的已打开目录对象结构的指针。
  • 返回值:包含在FRESULT结构体,不再详细介绍。

3.3 f_readdir函数

  • 函数功能:读取目录条目。
  • 函数原型:FRESULT f_readdir (DIR* dp, FILINFO* fno);
  • 输入参数:*dp:指向由 f _ opendir 函数创建的目录对象的指针;
    *fno:指向文件信息结构的指针,以存储有关已读项的信息;
  • 返回值:包含在FRESULT结构体,不再详细介绍。
  • 注意事项:f_readdir函数按顺序读取目录项、关于文件和目录的信息。通过重复调用 f _ readdir 函数,可以读取目录中的所有项。

  当启用相对路径特性(_ FS _ RPATH >= 1)时,点条目不会被过滤掉,它们将出现在读取条目中。当所有目录项都已读取且没有要读取的项时,空字符串存储在 fno-> fname []中,不会出现任何错误。当指向 fno 的空指针被赋值时,目录对象的读索引将被重绕。

  启用 LFN 特性(长文件名)后,文件信息结构中的 fno-> lfname 和 fno-> lfsize 在使用之前必须使用有效值进行初始化。lfname 指向 LFN 读取缓冲区。lfsize 是以 TCHAR 为单位的 LFN 读缓冲区的大小。如果不需要 LFN,则将 lfname设置为一个空指针,则不返回 LFN。

  这里简单介绍几句相对路径绝对路径,至于更加详细的内容还需要大家自行搜索。其实很好理解,绝对路径是指文件在硬盘上真正存在的路径,绝对路径是唯一的,只有一个,而相对路径是相对于当前目录或者当前工作目录的路径,表示文件相对于当前位置的路径。我们常见的带盘符的路径都是绝对路径,比如C:\Users\de’l’l\Desktop\doc这种,而相对路径是相对一个目标对象而言的,它有自己的表示方式,“.”表示当前所在目录,“…”代表上一层目录,“…\”代表上一层目录的上一层目录。

  对于f_readdir函数,给出了示例程序,这里贴一下,后续会使用该函数来打印一下某个特定文件夹下的文件

FRESULT scan_files (char* path        /* Start node to be scanned (also used as work area) */
)
{FRESULT res;FILINFO fno;DIR dir;int i;char *fn;   /* This function assumes non-Unicode configuration */
#if _USE_LFNstatic char lfn[_MAX_LFN + 1];   /* Buffer to store the LFN */fno.lfname = lfn;fno.lfsize = sizeof lfn;
#endifres = f_opendir(&dir, path);                       /* Open the directory */if (res == FR_OK) {i = strlen(path);for (;;) {res = f_readdir(&dir, &fno);                   /* Read a directory item */if (res != FR_OK || fno.fname[0] == 0) break;  /* Break on error or end of dir */if (fno.fname[0] == '.') continue;             /* Ignore dot entry */
#if _USE_LFNfn = *fno.lfname ? fno.lfname : fno.fname;
#elsefn = fno.fname;
#endifif (fno.fattrib & AM_DIR) {                    /* It is a directory */sprintf(&path[i], "/%s", fn);res = scan_files(path);path[i] = 0;if (res != FR_OK) break;} else {                                       /* It is a file. */printf("%s/%s\n", path, fn);}}f_closedir(&dir);}return res;
}

四、文件/目录管理函数

  下面介绍的这几个文件/目录管理函数的使用都比较简单,下面就不再单独给出应用示例了。

4.1 f_unlink函数

  • 函数功能:删除一个文件或子目录。
  • 函数原型:FRESULT f_unlink (const TCHAR* path);
  • 输入参数:*path:文件/文件夹路径。
  • 返回值:包含在FRESULT结构体,不再详细介绍。
  • 注意事项:如果要删除的对象的条件适用于以下条件,则无法使用本函数删除
        文件/子目录不能有只读属性(AM _ RDO) ,否则函数将被 FR _ DENIED 拒绝。
        子目录必须为空并且不能被工作目录,否则函数将被拒绝。
        当启用文件锁定功能时,它将被安全地拒绝。

4.2 f_rename函数

  • 函数功能:重命名文件或子目录。
  • 函数原型:FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new);
  • 输入参数:*path_old:旧对象名称;
    *path_new:新对象名称;
  • 返回值:包含在FRESULT结构体,不再详细介绍。
  • 注意事项:要重命名的对象不能是打开的对象。当启用文件锁定功能时,可以安全地拒绝这种错误操作。

4.3 f_mkdir函数

  • 函数功能:创建一个新目录。
  • 函数原型:FRESULT f_mkdir (const TCHAR* path);
  • 输入参数:*path:目录名。
  • 返回值:包含在FRESULT结构体,不再详细介绍。

五、示例程序

5.1 文件操作函数使用示例

  为了方便大家更好地理解FATFS的API函数的使用方法,我们这里通过一个小例子来演示一下,本例需要用到以下内容

  • 一张格式化过的空的SD卡;
  • 一个可以插SD卡的开发板或模块(这里使用的是STM32F103ZET6核心板);
  • 一块LCD显示屏(屏幕主要是为了显示提示信息,可有可无,可以用串口来代替)

  本例主要目的是在一张空的SD卡中创建并打开一个新的.txt文件,向文件中写入“ABCDEFGH”,然后读取文件内容并显示,最后读取一下文件大小。

  这里贴一下核心代码,代码中有个别打开文件和关闭文件的操作没有进行返回值检测,不影响实际测试,这里特地说明一下。

  f_mount(fs[0],"0:",1); 					//挂载SD卡// 打开一个文件,如果文件不存在,则创建一个res = f_open(&fil, "ERTUElec.txt",FA_OPEN_ALWAYS	| FA_WRITE);// 判断是否创建成功if (!res){LCD_ShowString(30,80,200,16,16,"File Creat Success!");}else{LCD_ShowString(30,80,200,16,16,"File Creat faild!  ");}// 写入数据res = f_write(&fil,&writeData[0],8,(UINT*)&bw);// 判断是否写入成功if (!res){LCD_ShowString(30,100,200,16,16,"File Write Success!");f_close(&fil);}else{LCD_ShowString(30,100,200,16,16,"File Write faild!  ");}f_open(&fil, "ERTUElec.txt",FA_READ);// 读取文件res = f_read(&fil,&readData[0],8,(UINT*)&br);// 判断是否读取成功if (!res){LCD_ShowString(30,120,200,16,16,"File Read Success!");}else{LCD_ShowString(30,120,200,16,16,"File Read faild!  ");}// 关闭打开的文件res = f_close(&fil);// 判断是否关闭成功if (!res){LCD_ShowString(30,140,200,16,16,"File Close Success!");}else{LCD_ShowString(30,140,200,16,16,"File Close faild!  ");}// 显示读取内容sprintf ((char*)string,"Content is %s",readData);LCD_ShowString(30,160,200,16,16,string);// 获取文件大小(字节数)size = f_size(&fil);// 显示文件大小sprintf ((char*)string,"Size is %d",size);LCD_ShowString(30,180,200,16,16,string);

  下面看一下LCD上显示的信息

LCD显示信息

5.2 目录操作函数使用示例

  本示例比较简单,就是使用f_readdir函数来读取一个特定文件加下的全部文件名并通过串口打印。首先我们在SD卡中新建一个文件夹,文件夹内添加一些文件用来测试

SD卡内容
  然后我们利用介绍f_readdir函数时给出的示例函数将NEW文件夹内的全部文件名通过串口打印出来,示例函数在上面已经给出了,这里就不再重复介绍了,在使用时只需要输入文件夹路径即可

	scan_files("0:/NEW");

  上电后观察串口输出内容

串口输出内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/741433.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二分搜索树和AVL树

问题 跑道预订系统。一个飞机场只有一个飞机跑道&#xff0c;需要为未来的飞机着陆预留空闲的跑道。飞机预订的着陆时间为t&#xff0c;假如没有其他的计划在(t-k,tk)的时间内着陆的飞机&#xff0c;则将t加入集合R。其中k是变量。请问有没有一种时间复杂度为O(logn)的算法解决…

增强PLMs可塑性!MetaAI | 提出主动遗忘机制,加快模型收敛,准确率高出21.2%!

引言 在自然语言处理领域&#xff0c;预训练语言模型&#xff08;PLMs&#xff09;扮演着至关重要的角色&#xff0c;它可以根据任务需求&#xff0c;可迁移至各种下游任务中。然而&#xff0c;PLMs在适应新语言时面临挑战&#xff0c;尤其是在数据和计算资源受限的情况下。本…

数据结构与算法----复习Part 14 (树与二叉树)

本系列是算法通关手册LeeCode的学习笔记 算法通关手册&#xff08;LeetCode&#xff09; | 算法通关手册&#xff08;LeetCode&#xff09; (itcharge.cn) 目录 一&#xff0c;树&#xff08;Tree&#xff09; 树的相关术语 节点间关系 树的其他术语 二&#xff0c;二叉…

比较JavaScript中的for...in和for...of循环

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

linux解析域名指令 nslookup 或者 host

host www.baidu.com 第二种方法 nslookup www.baidu.com 注意&#xff1a;ns是name server之意

【包邮送书】Elasticsearch 通过索引阻塞实现数据保护深入解析

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。关…

回收小程序系统后台管理功能

会员管理&#xff1a;管理员可以查看和管理会员的基本信息&#xff0c;如姓名、联系方式、寄送地址和订单记录等。 产品管理&#xff1a;对回收物品进行管理&#xff0c;包括分类、规格设定、数据统计等。 订单管理&#xff1a;对所有订单进行追踪和管理&#xff0c;确保订单处…

Leetcode 543. 二叉树的直径

题目描述&#xff1a; 给你一棵二叉树的根节点&#xff0c;返回该树的 直径 。 二叉树的 直径 是指树中任意两个节点之间最长路径的 长度 。这条路径可能经过也可能不经过根节点 root 。 两节点之间路径的 长度 由它们之间边数表示。 示例 1&#xff1a; 输入&#xff1a;ro…

汽车屏类产品(五):仪表Cluster常用芯片i.MX117x

前言: 仪表一般就是指方向盘前面那个表盘。做仪表的芯片最主要需要支持显示Display,而仪表的主要排版布局多种多样,但是主旨显示内容不尽相同。 仪表需求: 1、rpm转速表盘 仪表Cluster一般会有转速表盘rpm,单位一般是x1000,大部分汽车仪表范围就是0~8,也就是最高8000…

MySQL安装使用(mac、windows)

目录 macOS环境 一、下载MySQL 二、环境变量 三、启动 MySql 四、初始化密码设置 windows环境 一、下载 二、 环境配置 三、安装mysql 1.初始化mysql 2.安装Mysql服务 3.更改密码 四、检验 1.查看默认安装的数据库 2.其他操作 macOS环境 一、下载MySQL 打开 MyS…

用 Qt 不怕被告吗?

用 Qt 不怕被告吗? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Qt 的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01; 收律师函不…

云浮肇庆三维扫描钣金铸件抄数逆向设计外观画3D图上门抄数服务

钣金铸件抄数逆向设计画图是一项精密而富有挑战性的工作&#xff0c;它要求工程师具备深厚的专业知识和丰富的实践经验。3D抄数&#xff0c;即是通过精密测量设备获取钣金铸件的三维数据&#xff0c;为后续的逆向设计提供基础。逆向设计则是指根据已有的实物或模型&#xff0c;…

鸿蒙Harmony应用开发—ArkTS声明式开发(基础手势:StepperItem)

用作Stepper组件的页面子组件。 说明&#xff1a; 该组件从API Version 8开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 支持单个子组件。 接口 StepperItem() 属性 参数名参数类型参数描述prevLabelstring设置左侧文本按钮内…

2024年软考计划开始了,你准备好了吗?

目录标题 2024年度计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试工作计划计算机软考中级科目哪个含金量最高&#xff1f;报考流程和说明 2024年度计算机技术与软件专业技术资格&#xff08;水平&#xff09;考试工作计划 一、2024年度计算机软件资格考试(初级…

<Linux> 线程控制

目录 一、线程资源的分配 &#xff08;一&#xff09;线程私有资源 &#xff08;二&#xff09;线程共享资源 二、原生线程库 三、线程控制接口 &#xff08;一&#xff09;线程创建 - pthread_create() 1. 一个线程 2. 一批线程 &#xff08;二&#xff09;线程等待 …

linux 新增定时任务

1、创建定时任务 crontab -e 2、加入定时任务规则 0 2 * * * /usr1/local/mysql-backup/backup.sh 说明&#xff1a;backup.sh是sh脚本 3、重启定时任务 service crond restart 扩展 1、查看定时任务列表 crontab -l 2、需要修改定时任务 crontab -e

BUUCTF---web---[护网杯 2018]easy_tornado1

1.点开题目链接 2.依次点开文件链接 3.通过第一个信息可知&#xff0c;flag在文件名为/fllllllllllllag这个里面&#xff0c;第二个信息中的render是渲染函数&#xff0c;第三个个信息中是一个md5加解密&#xff0c;因为filename我们已经知道&#xff0c;所以我们需要找到cooki…

哪些数据可视化工具适合初学者使用?

数据建模及可视化平台&#xff0c;提供一站式全链路数据生命周期管理方案&#xff0c;支持数据建模&#xff0c;支持报表、图谱、大屏可视化应用的快速构建&#xff0c;支持AIBI探索实践&#xff0c;全流程免代码&#xff0c;免费使用 1、功能结构 2、技术架构 3、功能清单

2024年独立站C端只靠SEO还有机会吗?(川圣SEO)蜘蛛池

baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; baidu搜索&#xff1a;如何联系八爪鱼SEO&#xff1f; 2024年独立站C端只靠SEO还有机会吗&#xff1f;#蜘蛛池SEO 都2024年了&#xff0c;你的外贸独立站推广还需要…

盘点Python中4种读取JSON文件和提取JSON文件内容的方法

目录 一、使用json模块的load()方法 二、使用json模块的loads()方法 三、使用pandas库的read_json()方法 四、使用第三方库如requests从网络API获取JSON数据 总结 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;它基于EC…