如何正确得到FAT文件系统剩余容量
2006-06-04 09:47
225 查看
对于win32系统,可以调用api函数GetDiskFreeSpace得到磁盘的总容量和剩余容量,但在嵌入式设备里面,就需要分析FAT表信息然后计算取得了。
众所周知,FAT有三个版本FAT12、FAT16和FAT32,通过计算FAT表中的空闲簇数,就可以计算出磁盘的剩余容量了。对于FAT12,在FAT表中每簇使用12bit来表示,相应地,FAT16和FAT32则使用16位和32位来表示一个簇。
文件系统类型的判断
首先,我们要得到磁盘的BPB。一般来说,BPB位于磁盘的第0,32或63扇区,于是我们可以很简单地分别读取这三个扇区的内容,判断哪一个才是正确的BPB。
找出BPB后,就可以通过BPB来判断文件系统的类型。因为三种文件系统的空间算法各不相同,所以正确地判断文件系统类型很重要。在进行磁盘格式化的时候,如果计算出磁盘的可用簇数小于0xFF5(也就是12位可以表示),就格式化成FAT12,如果可用簇数大于0xFFF5(即16位表示不下),就应为FAT32,否则就是FAT16。如FAT32白皮书所述: This is the one and only way that FAT type is determined。这是微软的推荐做法。但事实上,很多格式化工具并不遵循这个规则。所以使用可用簇数来判断文件系统类型的方法并不可靠。
实际上,如果BPB中的BPB_FATSz16为0,则表示此文件系统一定是FAT32,然后再依据可用簇数来判断是FAT12或FAT16 。如下:
if(bpb->BPB_FATSz16)
{ //fat12 or fat16
if (m_max_clust >= 0xFF5)
{
get_fat16_freesector(); //fat16
}
else
{
get_fat12_freesector(); //fat12
}
}
else
{
get_fat32_freesector(); //fat32
}
可用簇的计算
上文提到了可用簇,所谓可用簇是指文件系统中真正能用来存放数据的簇。也就是要除掉MBR、BPB、保留扇区、FAT和FDT这些空间。如果确定了BPB的位置,可以直接得到保留扇区的大小,但FAT表大小和FDT表大小需要通过计算。
FAT偏移由BPB偏移加上保留扇区数得到。FAT大小由FAT份数乘以每份FAT的大小得到。FDT紧接在最后一个FAT表之后,其大小由根目录项数*32/512得到。
把总的扇区数减去系统所占的扇区数,就可以得到可用的扇区数。但FAT是以簇而非以扇区为最小单位的,所以把总扇区数除以每簇扇区数,就能得到可用的簇数了。其实这个值并非一定能除得尽,剩余不足一个簇的扇区实际上白白被浪费掉了
//得到文件系统总扇区数
if(bpb->BPB_FATSz16 && bpb->BPB_TotSec16)
m_total_sector = bpb->BPB_TotSec16; //fat16/12
else
m_total_sector = bpb->BPB_TotSec32; //fat32
//得到FDT所占的扇区数
m_num_fdt_sector = (bpb->BPB_RootEntCnt * 32)/512;
//得到fat1偏移
m_fat_offset = m_bpb_offset + bpb->BPB_RsvdSecCnt; //fat1=bpb+保留扇区数
//得到FDT表所在的偏移
if(bpb->BPB_FATSz16)
{
m_fdt_offset = m_fat_offset +
bpb->BPB_NumFATs * bpb->BPB_FATSz16; //fat16/12
}
else
{
m_fdt_offset = m_fat_offset +
bpb->BPB_NumFATs * bpb->FATBS.FAT32BS.BPB_FATSz32; //fat32
}
//文件系统占的数据大小=目录区偏移-BPB偏移+目录区大小
systemSector = (m_fdt_offset - m_bpb_offset) + m_num_fdt_sector;
//有效的扇区数->有效的簇数
m_max_clust = ((m_total_sector - systemSector)/bpb->BPB_SecPerClus);
分析FAT表得到剩余容量
可用簇数乘以簇大小,就是磁盘的总容量。分析FAT,把未用的簇统计出来,就是磁盘的剩余空间。
FAT表的前两项是系统占用的,所以我们要从第三个项开始统计,循环读入FAT表,直到算完所有的簇,该项为零表示簇空闲。值得注意的是FAT12,由于其一位只用12位来表示,所以奇偶簇的判断方法是不一样的。
FAT32的加速
FAT32的磁盘容量通常很大,所以FAT表很大,如果每次计算总容量都从头扫描一次FAT表,显示是很慢。考虑到这一点,FAT32还新增加了一个FSInfo扇区,保存着当前磁盘剩余簇数和下一个空闲簇地址。从BPB中可以知道FSInfo的位置,读取FSInfo扇区,如果FSInfo.FSI_Free_Count有效(不等于0xFFFFFFFF),则此值为当前磁盘的剩余容量。windows每次改变磁盘大小后,都会去更新这个值。如果此值不正确,那就得重新分析FAT表了。
disk_read_sector(bpb->FATBS.FAT32BS.BPB_FSInfo , 1, buffer);
info = (TFSInfo*)buffer;
if(info->FSI_LeadSig == 0x41615252 && info->FSI_TrailSig==0xAA550000)
{
if(info->FSI_Free_Count != -1)
{
m_disk_free_space = info->FSI_Free_Count;
}
}
如果有错误,请告之,MSN:szskyler@msn.com
众所周知,FAT有三个版本FAT12、FAT16和FAT32,通过计算FAT表中的空闲簇数,就可以计算出磁盘的剩余容量了。对于FAT12,在FAT表中每簇使用12bit来表示,相应地,FAT16和FAT32则使用16位和32位来表示一个簇。
文件系统类型的判断
首先,我们要得到磁盘的BPB。一般来说,BPB位于磁盘的第0,32或63扇区,于是我们可以很简单地分别读取这三个扇区的内容,判断哪一个才是正确的BPB。
找出BPB后,就可以通过BPB来判断文件系统的类型。因为三种文件系统的空间算法各不相同,所以正确地判断文件系统类型很重要。在进行磁盘格式化的时候,如果计算出磁盘的可用簇数小于0xFF5(也就是12位可以表示),就格式化成FAT12,如果可用簇数大于0xFFF5(即16位表示不下),就应为FAT32,否则就是FAT16。如FAT32白皮书所述: This is the one and only way that FAT type is determined。这是微软的推荐做法。但事实上,很多格式化工具并不遵循这个规则。所以使用可用簇数来判断文件系统类型的方法并不可靠。
实际上,如果BPB中的BPB_FATSz16为0,则表示此文件系统一定是FAT32,然后再依据可用簇数来判断是FAT12或FAT16 。如下:
if(bpb->BPB_FATSz16)
{ //fat12 or fat16
if (m_max_clust >= 0xFF5)
{
get_fat16_freesector(); //fat16
}
else
{
get_fat12_freesector(); //fat12
}
}
else
{
get_fat32_freesector(); //fat32
}
可用簇的计算
上文提到了可用簇,所谓可用簇是指文件系统中真正能用来存放数据的簇。也就是要除掉MBR、BPB、保留扇区、FAT和FDT这些空间。如果确定了BPB的位置,可以直接得到保留扇区的大小,但FAT表大小和FDT表大小需要通过计算。
FAT偏移由BPB偏移加上保留扇区数得到。FAT大小由FAT份数乘以每份FAT的大小得到。FDT紧接在最后一个FAT表之后,其大小由根目录项数*32/512得到。
把总的扇区数减去系统所占的扇区数,就可以得到可用的扇区数。但FAT是以簇而非以扇区为最小单位的,所以把总扇区数除以每簇扇区数,就能得到可用的簇数了。其实这个值并非一定能除得尽,剩余不足一个簇的扇区实际上白白被浪费掉了
//得到文件系统总扇区数
if(bpb->BPB_FATSz16 && bpb->BPB_TotSec16)
m_total_sector = bpb->BPB_TotSec16; //fat16/12
else
m_total_sector = bpb->BPB_TotSec32; //fat32
//得到FDT所占的扇区数
m_num_fdt_sector = (bpb->BPB_RootEntCnt * 32)/512;
//得到fat1偏移
m_fat_offset = m_bpb_offset + bpb->BPB_RsvdSecCnt; //fat1=bpb+保留扇区数
//得到FDT表所在的偏移
if(bpb->BPB_FATSz16)
{
m_fdt_offset = m_fat_offset +
bpb->BPB_NumFATs * bpb->BPB_FATSz16; //fat16/12
}
else
{
m_fdt_offset = m_fat_offset +
bpb->BPB_NumFATs * bpb->FATBS.FAT32BS.BPB_FATSz32; //fat32
}
//文件系统占的数据大小=目录区偏移-BPB偏移+目录区大小
systemSector = (m_fdt_offset - m_bpb_offset) + m_num_fdt_sector;
//有效的扇区数->有效的簇数
m_max_clust = ((m_total_sector - systemSector)/bpb->BPB_SecPerClus);
分析FAT表得到剩余容量
可用簇数乘以簇大小,就是磁盘的总容量。分析FAT,把未用的簇统计出来,就是磁盘的剩余空间。
FAT表的前两项是系统占用的,所以我们要从第三个项开始统计,循环读入FAT表,直到算完所有的簇,该项为零表示簇空闲。值得注意的是FAT12,由于其一位只用12位来表示,所以奇偶簇的判断方法是不一样的。
FAT32的加速
FAT32的磁盘容量通常很大,所以FAT表很大,如果每次计算总容量都从头扫描一次FAT表,显示是很慢。考虑到这一点,FAT32还新增加了一个FSInfo扇区,保存着当前磁盘剩余簇数和下一个空闲簇地址。从BPB中可以知道FSInfo的位置,读取FSInfo扇区,如果FSInfo.FSI_Free_Count有效(不等于0xFFFFFFFF),则此值为当前磁盘的剩余容量。windows每次改变磁盘大小后,都会去更新这个值。如果此值不正确,那就得重新分析FAT表了。
disk_read_sector(bpb->FATBS.FAT32BS.BPB_FSInfo , 1, buffer);
info = (TFSInfo*)buffer;
if(info->FSI_LeadSig == 0x41615252 && info->FSI_TrailSig==0xAA550000)
{
if(info->FSI_Free_Count != -1)
{
m_disk_free_space = info->FSI_Free_Count;
}
}
如果有错误,请告之,MSN:szskyler@msn.com
相关文章推荐
- 正确得到FAT文件系统剩余容量
- C#接收C++动态库返回字符串char*,在C#端如何接收并得到正确的字符串
- mysql中的存储过程使用事物后如何正确得到影响行数
- 如何得到正确的执行计划
- Flex Alert的匿名回调函数如何得到正确的this
- 关于J2EE项目中三层架构如何在开发中得到正确的实施
- STM32F101 如何正确启用内部晶振,并得到36MHZ频率?
- 如何使你的Sql 语句可以和null 值比较得到正确的结果,而不是永远都返回0条记录
- 如何正确的得到屏幕大小信息?
- 如何正确得到某个元素的位置
- 如何得到拨号网络传输速度
- 如何得到硬盘序列号[C#]
- Lucene.Net中 FSDirectory存储方式下一个 Document是如何得到的
- 学习网页制作中如何在正确选取和使用 CSS 单位
- Js如何得到request的值呢?
- 如何解决VC "应用程序无法启动,因为应用程序的并行配置不正确 sxstrace.exe"问题
- Git 在团队中的最佳实践--如何正确使用Git Flow
- 【Excle数据透视表】如何得到数据透视表中某个汇总行的明细数据
- 如何处理Xshell中CUI程序中行显示不正确
- 如何得到唯一的硬盘序号