【FATFS】f_lseek函数详细解析

FATFS f_lseek函数详细解析

       f_lseek 是 FatFs 文件系统库中的一个函数,用于移动文件指针到指定的位置。这个函数的主要作用是调整文件对象的读写位置,可以用于在文件中随机访问数据。通过 f_lseek,可以实现类似于文件跳转、追加写操作等功能。

FRESULT f_lseek (FIL* fp,        /* 文件对象指针 */FSIZE_t ofs     /* 从文件开头开始的偏移量 */
)
{FRESULT res;     // 定义函数返回结果类型变量FATFS *fs;       // 文件系统对象指针DWORD clst, bcs; // 集群(cluster)和集群大小(byte per cluster)LBA_t nsect;     // 逻辑扇区号FSIZE_t ifptr;   // 文件指针当前的位置
#if FF_USE_FASTSEEKDWORD cl, pcl, ncl, tcl, tlen, ulen; // 用于快速查找的变量DWORD *tbl;      // 集群链表指针LBA_t dsc;       // 物理扇区号
#endifres = validate(&fp->obj, &fs);      // 验证文件对象的有效性if (res == FR_OK) res = (FRESULT)fp->err;  // 检查是否有文件操作错误
#if FF_FS_EXFAT && !FF_FS_READONLYif (res == FR_OK && fs->fs_type == FS_EXFAT) {res = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF);  // 如果需要,填充FAT表中的最后一个片段}
#endifif (res != FR_OK) LEAVE_FF(fs, res);  // 如果出错,退出并返回结果#if FF_USE_FASTSEEKif (fp->cltbl) {    // 如果启用了快速查找if (ofs == CREATE_LINKMAP) {  // 如果是创建集群链表tbl = fp->cltbl;          // 获取集群链表表头tlen = *tbl++; ulen = 2;  // 获取链表的长度和使用项cl = fp->obj.sclust;      // 获取集群链表的起始集群if (cl != 0) {do {tcl = cl; ncl = 0; ulen += 2;  // 初始化集群链的相关变量do {pcl = cl; ncl++;   // 获取连续集群链长度cl = get_fat(&fp->obj, cl); // 获取下一个集群if (cl <= 1) ABORT(fs, FR_INT_ERR);   // 处理集群链中的错误if (cl == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);  // 处理磁盘错误} while (cl == pcl + 1); // 持续获取集群链,直到找到不连续的集群if (ulen <= tlen) {   // 如果链表有足够空间*tbl++ = ncl; *tbl++ = tcl;  // 存储链表中的集群数和顶集群}} while (cl < fs->n_fatent); // 重复操作直到集群链结束}*fp->cltbl = ulen;  // 更新链表的使用项if (ulen <= tlen) {*tbl = 0;  // 链表结束} else {res = FR_NOT_ENOUGH_CORE;  // 如果链表空间不足,返回错误}} else {    // 否则进行快速查找if (ofs > fp->obj.objsize) ofs = fp->obj.objsize; // 如果偏移量超过文件大小,则限制为文件大小fp->fptr = ofs;   // 更新文件指针位置if (ofs > 0) {fp->clust = clmt_clust(fp, ofs - 1); // 根据偏移量查找集群dsc = clst2sect(fs, fp->clust); // 获取集群的扇区号if (dsc == 0) ABORT(fs, FR_INT_ERR);  // 错误处理dsc += (DWORD)((ofs - 1) / SS(fs)) & (fs->csize - 1); // 计算扇区内的偏移if (fp->fptr % SS(fs) && dsc != fp->sect) {  // 如果需要,重新加载扇区缓存
#if !FF_FS_TINY
#if !FF_FS_READONLYif (fp->flag & FA_DIRTY) {   // 如果扇区缓存需要写回if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); // 写入磁盘fp->flag &= (BYTE)~FA_DIRTY;  // 清除脏标记}
#endifif (disk_read(fs->pdrv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);  // 读取当前扇区
#endiffp->sect = dsc;  // 更新文件对象的扇区号}}}} else
#endif/* 正常查找 */{
#if FF_FS_EXFATif (fs->fs_type != FS_EXFAT && ofs >= 0x100000000) ofs = 0xFFFFFFFF;  // 如果文件系统不是exFAT,最大偏移量限制为4GB
#endifif (ofs > fp->obj.objsize && (FF_FS_READONLY || !(fp->flag & FA_WRITE))) {  // 如果是只读模式,偏移量不能超过文件大小ofs = fp->obj.objsize;  // 限制偏移量为文件大小}ifptr = fp->fptr;  // 保存当前文件指针fp->fptr = nsect = 0;  // 重置文件指针和扇区号if (ofs > 0) {bcs = (DWORD)fs->csize * SS(fs);  // 获取每个集群的字节数if (ifptr > 0 && (ofs - 1) / bcs >= (ifptr - 1) / bcs) {  // 如果是前向查找fp->fptr = (ifptr - 1) & ~(FSIZE_t)(bcs - 1);  // 从当前集群开始ofs -= fp->fptr;clst = fp->clust;} else {  // 如果是后向查找clst = fp->obj.sclust;  // 从第一个集群开始
#if !FF_FS_READONLYif (clst == 0) {  // 如果没有集群链,创建新链clst = create_chain(&fp->obj, 0);if (clst == 1) ABORT(fs, FR_INT_ERR);if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);fp->obj.sclust = clst;}
#endiffp->clust = clst;  // 更新文件的当前集群}if (clst != 0) {while (ofs > bcs) {  // 集群跟踪循环ofs -= bcs; fp->fptr += bcs;
#if !FF_FS_READONLYif (fp->flag & FA_WRITE) {  // 如果是写入模式if (FF_FS_EXFAT && fp->fptr > fp->obj.objsize) {  // exFAT下需要更新文件大小fp->obj.objsize = fp->fptr;fp->flag |= FA_MODIFIED;}clst = create_chain(&fp->obj, clst);  // 在集群链末尾扩展链if (clst == 0) {  // 如果磁盘满了,剪裁文件大小ofs = 0; break;}} else
#endif{clst = get_fat(&fp->obj, clst);  // 如果不是写入模式,则继续跟踪集群链}if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);  // 错误处理if (clst <= 1 || clst >= fs->n_fatent) ABORT(fs, FR_INT_ERR);  // 错误处理fp->clust = clst;  // 更新当前集群}fp->fptr += ofs;if (ofs % SS(fs)) {nsect = clst2sect(fs, clst);  // 获取当前扇区号if (nsect == 0) ABORT(fs, FR_INT_ERR);  // 错误处理nsect += (DWORD)(ofs / SS(fs));  // 计算在扇区内的偏移}}}if (!FF_FS_READONLY && fp->fptr > fp->obj.objsize) {  // 如果文件大小扩展,更新文件大小fp->obj.objsize = fp->fptr;fp->flag |= FA_MODIFIED;}if (fp->fptr % SS(fs) && nsect != fp->sect) {  // 如果需要,更新扇区缓存
#if !FF_FS_TINY
#if !FF_FS_READONLYif (fp->flag & FA_DIRTY) {  // 写回脏扇区缓存if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);fp->flag &= (BYTE)~FA_DIRTY;}
#endifif (disk_read(fs->pdrv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);  // 读取扇区
#endiffp->sect = nsect;  // 更新当前扇区号}}LEAVE_FF(fs, res);  // 退出并返回结果
}

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

《PMI-PBA认证与商业分析实战精析》 第3章 需要评估

本章涵盖的考试重点&#xff1a; 需要评估的四项活动 需要评估四项活动的可交付成果 需要评估相关活动的技术 商业论证的内容 情境说明书的格式 目的、目标和商业论证的层次结构 成本收益分析的四种财务计价方法 需要评估领域就是聚焦在目标定义上。 商业分析师所需要…

网络通信——OSPF协议(基础篇)

这里基础是因为没有讲解OSPF中的具体算法过程&#xff0c;以及其中很多小细节。后续会更新。 目录 一.OSPF的基础信息 二.认识OSPF中的Router ID 三.OSPF中的三张表 四.OSPF中的度量方法&#xff08;计算开销值&#xff09; 五. OSPF选举DR和BDR&#xff08;就是这个区域…

P3131 [USACO16JAN] Subsequences Summing to Sevens S Python题解

[USACO16JAN] Subsequences Summing to Sevens S 题目描述 Farmer John’s N N N cows are standing in a row, as they have a tendency to do from time to time. Each cow is labeled with a distinct integer ID number so FJ can tell them apart. FJ would like to ta…

咸鱼sign逆向分析与爬虫实现

目标&#xff1a;&#x1f41f;的搜索商品接口 这个站异步有点多&#xff0c;好在代码没什么混淆。加密的sign值我们可以通过搜索找到位置 sign值通过k赋值&#xff0c;k则是字符串拼接后传入i函数加密 除了开头的aff…&#xff0c;后面的都是明文没什么好说的&#xff0c;我…

Linux安装RabbitMQ安装

1. RabbitMQ介绍 1.1 RabbitMQ关键特性 异步消息传递&#xff1a;允许应用程序在不直接进行网络调用的情况下交换消息。 可靠性&#xff1a;支持消息持久化&#xff0c;确保消息不会在系统故障时丢失。 灵活的路由&#xff1a;支持多种路由选项&#xff0c;包括直接、主题、…

学习记录:js算法(四十九):二叉树的层序遍历

文章目录 二叉树的层序遍历网上思路队列循环 总结 二叉树的层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 图一&#xff1a; 示例 1&#xff1a;如图一 输入&#xff1a;roo…

线性代数书中求解齐次线性方程组、非齐次线性方程组方法的特点和缺陷(附实例讲解)

目录 一、克拉默法则 1. 方法概述 2. 例16(1) P45 3. 特点 (1) 只适用于系数矩阵是方阵 (2) 只适用于行列式非零 (3) 只适用于唯一解的情况 (4) 只适用于非齐次线性方程组 二、逆矩阵 1. 方法概述 2. 例16(2) P45 3. 特点 (1) 只适用于系数矩阵必须是方阵且可逆 …

链表OJ经典题目及思路总结(一)

目录 前言1.移除元素1.1 链表1.2 数组 2.双指针2.1 找链表的中间结点2.2 找倒数第k个结点 总结 前言 解代码题 先整体&#xff1a;首先数据结构链表的题一定要多画图&#xff0c;捋清问题的解决思路&#xff1b; 后局部&#xff1a;接着考虑每一步具体如何实现&#xff0c;框架…

CSP-J模拟赛(1)补题报告

前言&#xff1a; 1.交替出场&#xff08;alter) &#xff1a;10 2.翻翻转转&#xff08;filp)&#xff1a;0 3.方格取数&#xff08;square&#xff09;&#xff1a;0 4.圆圆中的方方&#xff08;round)&#xff1a;0 总结一下&#xff1a; 第一次考&#xff0c;没爆零就是胜…

Java面试必杀技为什么面试官都爱问源码?

你也许能说出一万个不知道原理源码也能胜任工作的理由。但是也改变不了&#xff0c;高质量的人才必须要通过原理源码来筛选的事实&#xff01; 不要抱怨没有时间学习&#xff0c;去年到今年&#xff0c;一年时间过去了&#xff0c;你是没时间学习&#xff0c;还是有时间也没学习…

大数据毕业设计选题推荐-个性化图书推荐系统-Python数据可视化-Hive-Hadoop-Spark

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、PHP、.NET、Node.js、GO、微信小程序、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇…

螺狮壳里做道场:老破机搭建的私人数据中心---Centos下Docker学习01(环境准备)

1 准备工作 由于创建数据中心需要安装很多服务器&#xff0c;这些服务器要耗费很所物理物理计算资源、存储资源、网络资源和软件资源&#xff0c;作为穷学生只有几百块的n手笔记本&#xff0c;不可能买十几台服务器来搭建数据中心&#xff0c;也不愿意跑实验室&#xff0c;想躺…

MySQL基础篇 - 多表查询

01 多表关系 【1】概念&#xff1a;项目开发中&#xff0c;在进行数据库表结构设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;分析并设计表结构&#xff0c;由于业务之间相互关联&#xff0c;所以各表结构之间也存在着各种联系&#xff0c;基本上分为三种…

音视频入门基础:FLV专题(10)——Script Tag实例分析

一、引言 在《音视频入门基础&#xff1a;FLV专题&#xff08;9&#xff09;——Script Tag简介》中对FLV文件的Script Tag进行了简介。下面用一个具体的例子来对Script Tag进行分析。 二、Script Tag的Tag header实例分析 用notepad打开《音视频入门基础&#xff1a;FLV专题…

超分服务的分量保存

分量说明 分量的概念主要是对于一个显卡和网络传输而言&#xff0c;显卡可以同时进行几个线程&#xff0c;多个显卡可以分布式进行量的同时进行AI识别&#xff0c;比如我们有cuda的显卡&#xff0c;cuda的核心量可以分给不同的分片视频&#xff0c;第一步先将视频减小&#xff…

Java 自定义异常及经验小结

1&#xff0e;java内置的异常类可以处理大部分异常情况。此外&#xff0c;用户还可以自定义异常&#xff0c;只需继承Exception类即可。 2&#xff0e;在程序中使用自定义异常类&#xff0c;大体可分为以下几个步骤&#xff1a; &#xff08;1&#xff09;创建自定义异常类 &…

VBA数据库解决方案第十五讲:Recordset集合中单个数据的精确处理

《VBA数据库解决方案》教程&#xff08;版权10090845&#xff09;是我推出的第二套教程&#xff0c;目前已经是第二版修订了。这套教程定位于中级&#xff0c;是学完字典后的另一个专题讲解。数据库是数据处理的利器&#xff0c;教程中详细介绍了利用ADO连接ACCDB和EXCEL的方法…

虚拟机、ubantu不能连接网络,解决办法

虚拟机、ubantu不能连接网络&#xff0c;解决办法 物理机OS&#xff1a; [Windows10 专业版](https://so.csdn.net/so/search?qWindows10 专业版&spm1001.2101.3001.7020) 虚拟机平台&#xff1a; VMware Workstation 16 Pro 虚拟机OS&#xff1a; Ubuntu 18.04 自动配…

适合初学者的[JAVA]: 基础面试题

目录 说明 前言 String/StringBuffer/StringBuilder区别 第一点: 第二点: 总结&#xff1a; 反射机制 JVM内存结构 运行时数据区域被划分为5个主要组件&#xff1a; 方法区&#xff08;Method Area&#xff09; 堆区&#xff08;Heap Area&#xff09; 栈区&#x…

SSM整合:图书管理系统

图书管理系统 一.环境 1.数据库环境 CREATE DATABASE ssmbuild;USE ssmbuild;DROP TABLE IF EXISTS books;CREATE TABLE books (bookID INT(10) NOT NULL AUTO_INCREMENT COMMENT 书id,bookName VARCHAR(100) NOT NULL COMMENT 书名,bookCounts INT(11) NOT NULL COMMENT 数量…