第四载、FAT12文件系统剖析2

本文深入剖析FAT12文件系统,介绍如何通过根目录项判断文件存在及读取文件内容。内容包括根目录的计算、根目录项的组成,以及利用FAT表组织分散存储的文件数据,阐述了FAT12中文件数据读取的链表思想。
摘要由CSDN通过智能技术生成

在上一章节《FAT12文件系统剖析1》中,我们把a.img启动软盘使用FreeDos系统格式化为FAT12文件系统的组织方式,并且向a.img软盘写入两个文件,同时通过FreeDos操作系统也查看了a.img软盘中的文件。之所以这么做,是因为主引导程序不可以超过512字节,所以主引导程序需要在基本的初始化工作完成后加载启动介质(这里是软盘a.img)中的启动程序到内存,然后跳转到对应内存处执行。

上一节我们是通过FreeDos操作系统来查看a.img软盘中FAT12根目录的目标文件,那么在程序中我们怎去判断目标文件是否存在FAT12根目录中?要解决这个问题,我们首先来了解FAT12的根目录在文件系统中的位置

上图中直接给了计算根目录大小的公式:根目录个数 * 每个根目录项大小 / 每个扇区大小 = 根目录占用的扇区数量,
其中根目录个数在上一章节我们已经求出,为0xe0,十进制为224,不熟悉的可以参考上一章节。每个根目录项大小为32字节,每个扇区大小为512字节,那么有 224 * 32 / 512 = 14,即根目录文件项在FAT12文件系统中总共占用14个扇区,也就是7168字节。

除了上边说的根目录区,我们还需要了解下根目录项,根目录由根目录项组成,上文中的224,就是FAT12文件系统有224个根目录项,一个根目录项代表根目录中的一个文件索引,每个根目录项中,包含了这个文件的基本信息,如下:

下边需要做的实验,便是读取FAT12中每个根目录项的内容并打印(代码在上章代码基础上增加更目录项的打印)

#include <QtCore/QCoreApplication>
#include <QFile>
#include <QDataStream>
#include <QDebug>

#pragma pack(push)
#pragma pack(1)

struct Fat12Header
{
    char BS_OEMName[8];
    ushort BPB_BytsPerSec;  //每扇区字节数,默认512字节
    uchar BPB_SecPerClus;   //每簇扇区数
    ushort BPB_RsvdSecCnt;
    uchar BPB_NumFATs;
    ushort BPB_RootEntCnt;  //最大跟目录文件数
    ushort BPB_TotSec16;
    uchar BPB_Media;
    ushort BPB_FATSz16;
    ushort BPB_SecPerTrk;
    ushort BPB_NumHeads;
    uint BPB_HiddSec;
    uint BPB_TotSec32;
    uchar BS_DrvNum;
    uchar BS_Reserved1;
    uchar BS_BootSig;
    uint BS_VolID;
    char BS_VolLab[11];
    char BS_FileSysType[8];
};

//根目录项结构体
struct RootEntry
{
    char DIR_Name[11];
    uchar DIR_Attr;
    uchar reserve[10];
    ushort DIR_WrtTime;
    ushort DIR_WrtDate;
    ushort DIR_FstClus;
    uint DIR_FileSize;
};

#pragma pack(pop)

void PrintHeader(Fat12Header& rf, QString p)
{
    QFile file(p);

    if( file.open(QIODevice::ReadOnly) )
    {
        QDataStream in(&file);

        file.seek(3);   //偏移开头3字节

        in.readRawData(reinterpret_cast<char*>(&rf), sizeof(rf));

        rf.BS_OEMName[7] = 0;
        rf.BS_VolLab[10] = 0;
        rf.BS_FileSysType[7] = 0;

        qDebug() << "BS_OEMName: " << rf.BS_OEMName;
        qDebug() << "BPB_BytsPerSec: " << hex << rf.BPB_BytsPerSec;
        qDebug() << "BPB_SecPerClus: " << hex << rf.BPB_SecPerClus;
        qDebug() << "BPB_RsvdSecCnt: " << hex << rf.BPB_RsvdSecCnt;
        qDebug() << "BPB_NumFATs: " << hex << rf.BPB_NumFATs;
        qDebug() << "BPB_RootEntCnt: " << hex << rf.BPB_RootEntCnt;
        qDebug() << "BPB_TotSec16: " << hex << rf.BPB_TotSec16;
        qDebug() << "BPB_Media: " << hex << rf.BPB_Media;
        qDebug() << "BPB_FATSz16: " << hex << rf.BPB_FATSz16;
        qDebug() << "BPB_SecPerTrk: " << hex << rf.BPB_SecPerTrk;
        qDebug() << "BPB_NumHeads: " << hex << rf.BPB_NumHeads;
        qDebug() << "BPB_HiddSec: " << hex << rf.BPB_HiddSec;
        qDebug() << "BPB_TotSec32: " << hex << rf.BPB_TotSec32;
        qDebug() << "BS_DrvNum: " << hex << rf.BS_DrvNum;
        qDebug() << "BS_Reserved1: " << hex << rf.BS_Reserved1;
        qDebug() <&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值