不用ReadFile读取文件(Part 2)

本文详细介绍了FAT32文件系统的结构及其关键组成部分,包括引导记录、BPB数据结构、文件分配表及文件目录表等内容,并提供了读取文件的具体步骤。

上篇说到引导记录(Boot Record),在讲解引导记录之前,有必要说明一下FAT文件系统的结

构,FAT文件系统的每个分区,由4个部分组成:  

    0 - 保留区域(Reserved Region)

    1 - 文件分配表区(FAT Region)

    2 - 根目录区(不存在于FAT32的分区中)

    3 - 文件和目录数据区(File and Directory Data Region)

这里的“保留区域”,我们所说的引导记录,就藏在这“保留区域”内,而且还是在前面。  

通过微软的FAT32规格书,我们可以知道,引导记录里包含一个比较重要的、叫做BPB(BIOS

Parameter Block)的数据结构,该结构的位置在引导记录(也就是分区的第一扇区)的最前面

,引导记录完整的结构如下:  

(备注:下表中以BPB_开头的字段隶属于BPB,以BS_开头的属于引导记录中其它的部分)

引导记录和BPB结构

Name

Offset (byte)

Size (bytes)

Description

BS_jmpBoot

0

3

Jump instruction to boot code. This field has two allowed forms:

jmpBoot[0] = 0xEB, jmpBoot[1] = 0x??, jmpBoot[2] = 0x90

and

jmpBoot[0] = 0xE9, jmpBoot[1] = 0x??, jmpBoot[2] = 0x??

 

0x?? indicates that any 8-bit value is allowed in that byte. What this forms is a three-byte Intel x86 unconditional branch (jump) instruction that jumps to the start of the operating system bootstrap code. This code typically occupies the rest of sector 0 of the volume following the BPB and possibly other sectors. Either of these forms is acceptable. JmpBoot[0] = 0xEB is the more frequently used format.

BS_OEMName

3

8

“MSWIN 4.1” There are many misconceptions about this field. It is only a name string. Microsoft operating systems don’t pay any attention to this field. Some FAT drivers do. This is the reason that the indicated string, “MSWIN 4.1” , is the recommended setting, because it is the setting least likely to cause compatibility problems. If you want to put something else in here, that is your option, but the result may be that some FAT drivers might not recognize the volume. Typically this is some indication of what system formatted the volume.

BPB_BytsPerSec

11

2

Count of bytes per sector. This value may take on only the following values: 512, 1024, 2048 or 4096. If maximum compatibility with old implementations is desired, only the value 512 should be used. There is a lot of FAT code in the world that is basically “hard wired” to 512 bytes per sector and doesn’t bother to check this field to make sure it is 512. Microsoft operating systems will properly support 1024, 2048, and 4096.

 

Note: Do not misinterpret these statements about maximum compatibility. If the media being recorded has a physical sector size N, you must use N and this must still be less than or equal to 4096. Maximum compatibility is achieved by only using media with specific sector sizes.

BPB_SecPerClus

13

1

Number of sectors per allocation unit. This value must be a power of 2 that is greater than 0. The legal values are 1, 2, 4, 8, 16, 32, 64, and 128. Note however, that a value should never be used that results in a “bytes per cluster” value (BPB_BytsPerSec * BPB_SecPerClus) greater than 32K (32 * 1024). There is a misconception that values greater than this are OK. Values that cause a cluster size greater than 32K bytes do not work properly; do not try to define one. Some versions of some systems allow 64K bytes per cluster value. Many application setup programs will not work correctly on such a FAT volume.


BPB_RsvdSecCnt

14

2

Number of reserved sectors in the Reserved region of the volume starting at the first sector of the volume. This field must not be 0. For FAT12 and FAT16 volumes, this value should never be anything other than 1. For FAT32 volumes, this value is typically 32. There is a lot of FAT code in the world “hard wired” to 1 reserved sector for FAT12 and FAT16 volumes and that doesn’t bother to check this field to make sure it is 1. Microsoft operating systems will properly support any non-zero value in this field.

BPB_NumFATs

16

1

The count of FAT data structures on the volume. This field should always contain the value 2 for any FAT volume of any type. Although any value greater than or equal to 1 is perfectly valid, many software programs and a few operating systems’ FAT file system drivers may not function properly if the value is something other than 2. All Microsoft file system drivers will support a value other than 2, but it is still highly recommended that no value other than 2 be used in this field.

 

The reason the standard value for this field is 2 is to provide redun­dancy for the FAT data structure so that if a sector goes bad in one of the FATs, that data is not lost because it is duplicated in the other FAT. On non-disk-based media, such as FLASH memory cards, where such redundancy is a useless feature, a value of 1 may be used to save the space that a second copy of the FAT uses, but some FAT file system drivers might not recognize such a volume properly.

BPB_RootEntCnt

17

2

For FAT12 and FAT16 volumes, this field contains the count of 32-byte directory entries in the root directory. For FAT32 volumes, this field must be set to 0. For FAT12 and FAT16 volumes, this value should always specify a count that when multiplied by 32 results in an even multiple of BPB_BytsPerSec. For maximum compatibility, FAT16 volumes should use the value 512.

BPB_TotSec16

19

2

This field is the old 16-bit total count of sectors on the volume. This count includes the count of all sectors in all four regions of the volume. This field can be 0; if it is 0, then BPB_TotSec32 must be non-zero. For FAT32 volumes, this field must be 0. For FAT12 and FAT16 volumes, this field contains the sector count, and BPB_TotSec32 is 0 if the total sector count “fits” (is less than 0x10000).

BPB_Media

21

1

0xF8 is the standard value for “fixed” (non-removable) media. For removable media, 0xF0 is frequently used. The legal values for this field are 0xF0, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, and 0xFF. The only other important point is that whatever value is put in here must also be put in the low byte of the FAT[0] entry. This dates back to the old MS-DOS 1.x media determination noted earlier and is no longer usually used for anything.

BPB_FATSz16

22

2

This field is the FAT12/FAT16 16-bit count of sectors occupied by ONE FAT. On FAT32 volumes this field must be 0, and BPB_FATSz32 contains the FAT size count.

BPB_SecPerTrk

24

2

Sectors per track for interrupt 0x13. This field is only relevant for media that have a geometry (volume is broken down into tracks by multiple heads and cylinders) and are visible on interrupt 0x13. This field contains the “sectors per track” geometry value.

BPB_NumHeads

26

2

Number of heads for interrupt 0x13. This field is relevant as discussed earlier for BPB_SecPerTrk. This field contains the one based “count of heads”. For example, on a 1.44 MB 3.5-inch floppy drive this value is 2.

BPB_HiddSec

28

4

Count of hidden sectors preceding the partition that contains this FAT volume. This field is generally only relevant for media visible on interrupt 0x13. This field should always be zero on media that are not partitioned. Exactly what value is appropriate is operating system specific.

BPB_TotSec32

32

4

This field is the new 32-bit total count of sectors on the volume. This count includes the count of all sectors in all four regions of the volume. This field can be 0; if it is 0, then BPB_TotSec16 must be non-zero. For FAT32 volumes, this field must be non-zero. For FAT12/FAT16 volumes, this field contains the sector count if BPB_TotSec16 is 0 (count is greater than or equal to 0x10000).

BPB_FATSz32

36

4

This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. This field is the FAT32 32-bit count of sectors occupied by ONE FAT. BPB_FATSz16 must be 0.

BPB_ExtFlags

40

2

This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media.

Bits 0-3  -- Zero-based number of active FAT. Only valid if mirroring is disabled.

Bits 4-6  -- Reserved.

Bit      7         -- 0 means the FAT is mirrored at runtime into all FATs.

               -- 1 means only one FAT is active; it is the one referenced in bits 0-3.

Bits 8-15   -- Reserved.

BPB_FSVer

42

2

This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. High byte is major revision number. Low byte is minor revision number. This is the version number of the FAT32 volume. This supports the ability to extend the FAT32 media type in the future without worrying about old FAT32 drivers mounting the volume. This document defines the version to 0:0.  If this field is non-zero, back-level Windows versions will not mount the volume.

NOTE:  Disk utilities should respect this field and not operate on volumes with a higher major or minor version number than that for which they were designed. FAT32 file system drivers must check this field and not mount the volume if it does not contain a version number that was defined at the time the driver was written.

BPB_RootClus

44

4

This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. This is set to the cluster number of the first cluster of the root directory, usually 2 but not required to be 2.

NOTE:  Disk utilities that change the location of the root directory should make every effort to place the first cluster of the root directory in the first non-bad cluster on the drive (i.e., in cluster 2, unless it’s marked bad). This is specified so that disk repair utilities can easily find the root directory if this field accidentally gets zeroed.

BPB_FSInfo

48

2

This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. Sector number of FSINFO structure in the reserved area of the FAT32 volume. Usually 1. 

NOTE: There will be a copy of the FSINFO structure in BackupBoot, but only the copy pointed to by this field will be kept up to date (i.e., both the primary and backup boot record will point to the same FSINFO sector).

BPB_BkBootSec

50

2

This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. If non-zero, indicates the sector number in the reserved area of the volume of a copy of the boot record. Usually 6. No value other than 6 is recommended.

BPB_Reserved

52

12

This field is only defined for FAT32 media and does not exist on FAT12 and FAT16 media. Reserved for future expansion. Code that formats FAT32 volumes should always set all of the bytes of this field to 0.

BS_DrvNum

64

1

This field has the same definition as it does for FAT12 and FAT16 media. The only difference for FAT32 media is that the field is at a different offset in the boot sector.

BS_Reserved1

65

1

This field has the same definition as it does for FAT12 and FAT16 media. The only difference for FAT32 media is that the field is at a different offset in the boot sector.

BS_BootSig

66

1

This field has the same definition as it does for FAT12 and FAT16 media. The only difference for FAT32 media is that the field is at a different offset in the boot sector.

BS_VolID

67

4

This field has the same definition as it does for FAT12 and FAT16 media. The only difference for FAT32 media is that the field is at a different offset in the boot sector.

BS_VolLab

71

11

This field has the same definition as it does for FAT12 and FAT16 media. The only difference for FAT32 media is that the field is at a different offset in the boot sector.

BS_FilSysType

82

8

Always set to the string FAT 32    .  Please see the note for this field in the FAT12/FAT16 section earlier. This field has nothing to do with FAT type determination.

 

其中需要特别注意的是BPB_RsvdSecCntBPB_RootClus,这两个字段分别指出了保留区所占的扇区数和

分区根目录的起始簇号。

 

紧挨着引导记录的是FAT本身。FAT只是文件簇号的一个链表,以下图中的文件a.txt为例,

FDT(文件目录表)中我们知道文件a.txt的首簇号为0x00000001FAT表中序号为0x00000001的项指向簇0x00000002,项0x00000002指向簇0x 000000C 8(200),项0x 000000C 8指向簇0xFFFFFFF7,设簇值为0xFFFFFFF7FAT项为文件的结束标志,则文件a.txt的簇链为“0x010x020xC 8 ,也就是说文件a.txt

的内容存放在这三个簇里面。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

突然间又冒出来一个新叫做FDT(文件目录表)的新东西,那我们到哪里去找FDT呢?答案是在FAT32里根本就

没有称做FDT的东西,也就是根本没有划分出一个区域来存放目录,目录只不过是一个DIR_Attr字段值为属性

ATTR_DIRECTORY的“文件”。另外一个区别是:目录里包含的是32-Byte的目录入口。

FAT 32-byte 的目录入口结构

Name

Offset (byte)

Size (bytes)

Description

DIR_Name

0

11

Short name.

DIR_Attr

11

1

File attributes:

ATTR_READ_ONLY                     0x01

ATTR_HIDDEN                                0x02

ATTR_SYSTEM                                0x04

ATTR_VOLUME_ID                        0x08

ATTR_DIRECTORY                         0x10

ATTR_ARCHIVE                             0x20

ATTR_LONG_NAME                      ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID

The upper two bits of the attribute byte are reserved and should always be set to 0 when a file is created and never modified or looked at after that.

DIR_NTRes

12

1

Reserved for use by Windows NT. Set value to 0 when a file is created and never modify or look at it after that.

DIR_CrtTimeTenth

13

1

Millisecond stamp at file creation time. This field actually contains a count of tenths of a second. The granularity of the seconds part of DIR_CrtTime is 2 seconds so this field is a count of tenths of a second and its valid value range is 0-199 inclusive.

DIR_CrtTime

14

2

Time file was created

DIR_CrtDate

16

2

Date file was created.

DIR_LstAccDate

18

2

Last access date. Note that there is no last access time, only a date. This is the date of last read or write. In the case of a write, this should be set to the same date as DIR_WrtDate.

DIR_FstClusHI

20

2

High word of this entry’s first cluster number (always 0 for a FAT12 or FAT16 volume).

DIR_WrtTime

22

2

Time of last write. Note that file creation is considered a write.

DIR_WrtDate

24

2

Date of last write. Note that file creation is considered a write.

DIR_FstClusLO

26

2

Low word of this entry’s first cluster number.

DIR_FileSize

28

4

32-bit DWORD holding this file’s size in bytes.

通过BPB结构中的BPB_RootClus字段我们知道根目录的首簇号,要读出根目录的内容(内容存放在“文件和目录

数据区”),还需要把簇号转化为扇区号,公式为:

       FirstSectorofCluster = ((N – 2) * BPB_SecPerClus) + FirstDataSector;

注:式子中的簇号减2(N – 2)是因为FAT的第0项与第1项被用来保存磁盘介质标志等信息,

  数据的起始簇号为2

 

其中N为任意一个簇号,FirstDataSector为数据区的起始扇区号,计算方法如下:

FirstDataSector = BPB_ResvdSecCnt + (BPB_NumFATs * FATSz) + RootDirSectors;

RootDirSections是根目录区的起始扇区号,由以下公式计算可得出:

RootDirSectors = ((BPB_RootEntCnt * 32) + (BPB_BytsPerSec – 1)) / BPB_BytsPerSec;

由于FAT32中并没有根目录区,BPB_RootEntCnt值永远为0,所以RootDirSections值也永远为0

  套用簇号转换为扇区号的公式,N取值为BPB_RootClus,得出的就是根目录所在的扇区号,利用Windows提供

FileSeeckReadFile函数,就可以读出指定扇区的内容。“目录文件”的内容是一个个的目录入口结构,这

个结构中就包含文件的起始簇号,利用FirstSectorofCluster的计算公式,我们就可以读出文件第一簇的内容,如

果文件大小超过一簇,就需要到文件分配表区中找到下一簇的簇号,设当前簇号为N,计算下一簇簇号的方法为:

FATOffset = N * 4; (FAT32:簇号占4个字节)

ThisFATSecNum = BPB_ResvdSecCnt + (FATOffset / BPB_BytsPerSec);

ThisFATEntOffset = FATOffset % BPB_BytsPerSec;

读入扇区号为ThisFATSecNum的内容到SecBuff,假设SecBuff为字节数组,则簇N的下一簇FAT32ClusEntryVal

计算方法为:

       FAT32ClusEntryVal = (*((DWORD *) &SecBuff[ThisFATEntOffset])) & 0x0FFFFFFF;

依次读入各个扇区,直到下一簇号为结束簇(0x0FFFFFF8)为止。

 

 

光说不练是你的风格,不是我的,我的是理论要联系实际。所以我还提供了一份代码,在这里。代码生成的exe

支持两种参数:

Cluster.exe /D C:/boot.ini  (Dump C:/boot.ini的内容,生成Testboot.ini)

Cluster.exe /S C:/Windows   (显示C:/Windows目录下的文件,类似dir命令)  

(注:程序暂不支持长文件名(即文件名长度超过11字节的文件)

 

参考资料链接:

         http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx

http://zhidao.baidu.com/question/13626098.html

 

 
<think>我们被要求将DXF文件转换为CAT文件。首先,需要明确DXF和CAT文件格式: - DXF(Drawing Exchange Format)是AutoCAD使用的矢量图形文件格式,用于CAD数据交换。 - CAT文件可能是CATIA(一种CAD软件)的文件格式,但通常CATIA使用的主要文件扩展名是.CATPart或.CATProduct。因此,这里的CAT文件可能指的是CATIA V5的零件文件(.CATPart)或装配文件(.CATProduct)。 然而,Python中并没有直接转换DXF到CATPart的内置库。这通常需要借助CAD软件的API(如CATIA的COM接口)或使用中间格式(如STEP)进行转换。 ### 方法1:使用OCC(Open Cascade)或FreeCAD 我们可以使用FreeCAD(一个开源的CAD软件)的Python API来读取DXF并导出为CATIA格式。FreeCAD支持多种格式,包括DXF和STEP,但直接导出为CATPart可能不支持。通常的做法是: 1. 将DXF导入FreeCAD。 2. 将模型保存为中间格式(如STEP)。 3. 使用CATIA将STEP文件转换为CATPart(这一步不在Python中,除非使用CATIA的COM接口)。 ### 方法2:使用CATIA的COM接口(仅Windows) 如果系统安装了CATIA,可以通过Python的win32com库调用CATIA的API进行转换。步骤大致如下: 1. 使用一个库(如ezdxf)读取DXF文件并构建几何体。 2. 通过COM接口将几何体导入CATIA并保存为CATPart。 ### 方法3:使用在线转换服务或第三方工具 也可以考虑使用第三方工具(如ODA File Converter)或在线转换服务,然后通过Python调用这些工具的命令行接口。 ### 具体步骤(以方法2为例,假设已安装CATIA) 由于CATIA的COM接口要求CATIA已安装,且通常用于Windows环境,以下是一个概念性步骤: 1. 安装必要的Python库: - `pywin32`:用于COM接口。 - `ezdxf`:用于读取DXF文件2. 使用`ezdxf`读取DXF文件,获取几何数据。 3. 启动CATIA,创建新零件,将几何数据通过COM接口导入。 4. 保存为CATPart文件。 ### 代码示例(概念性) ```python import win32com.client import ezdxf # 读取DXF文件 dxf_file = "input.dxf" doc = ezdxf.readfile(dxf_file) modelspace = doc.modelspace() # 启动CATIA catia = win32com.client.Dispatch("CATIA.Application") catia.Visible = True # 可见模式,调试用 documents = catia.Documents part_doc = documents.Add("Part") # 创建新零件文档 part = part_doc.Part # 获取Part对象 bodies = part.Bodies # 获取Bodies集合 body = bodies.Add() # 添加一个Body # 遍历DXF中的实体 for entity in modelspace: if entity.dxftype() == 'LINE': start = entity.dxf.start end = entity.dxf.end # 在CATIA中创建直线(这里需要转换为CATIA的API) # 注意:CATIA的API操作几何体较为复杂,需要创建草图并添加直线 # 其他类型实体类似处理 # 保存为CATPart文件 part_doc.SaveAs("output.CATPart") part_doc.Close() catia.Quit() ``` ### 注意事项 - 上述代码仅为概念演示,实际转换需要详细处理DXF中的各种实体(如圆、弧、多段线等)并转换为CATIA的几何元素。 - 直接转换复杂图形可能非常困难,因为两种CAD系统的建模方式不同。 - 对于复杂转换,建议使用中间格式(如STEP)并通过CATIA批量转换。 ### 替代方案:使用STEP格式 更实际的做法是: 1. 使用`ezdxf`读取DXF并导出为STEP文件(需要额外库,如`occcore`,但Python中STEP导出支持有限)。 2. 使用FreeCAD作为转换器(Python脚本控制FreeCAD): ```python import FreeCAD import Part import Import import Export # 读取DXF doc = FreeCAD.newDocument() Import.insert("input.dxf", doc.Name) # 导出为STEP Export.export(doc.Objects, "output.step") ``` 然后使用CATIA打开STEP文件并另存为CATPart(这一步可以自动化,但需要CATIA的COM接口)。 ### 总结 由于直接转换的复杂性,建议评估转换需求: - 如果转换不频繁,可以手动通过中间格式转换。 - 如果需要自动化,考虑使用FreeCAD导出STEP,然后通过CATIA的COM接口自动转换为CATPart。 相关问题: 1. 如何用Python读取DXF文件2. 如何使用FreeCAD的Python API进行CAD文件转换? 3. 如何通过COM接口控制CATIA? 4. DXF文件中的哪些几何元素可以转换为CATIA的几何体? 5. 是否有现成的Python库支持DXF到CATIA的转换?</think>### 将DXF转换为CAT文件的Python解决方案 DXF(Drawing Exchange Format)是AutoCAD的标准交换格式,而CAT文件通常指CATIA(CAD软件)的零件文件(.CATPart)或装配文件(.CATProduct)。Python中实现直接转换需要借助专业库或中间格式,以下是两种可行方法: --- ### 方法1:使用FreeCAD(开源方案) FreeCAD支持多种CAD格式转换,可通过Python脚本批量处理: ```python import FreeCAD import Part import Import import Export # 读取DXF文件 doc = FreeCAD.newDocument() Import.insert("input.dxf", doc.Name) # 导入DXF # 导出为CATIA V5格式 objects = doc.Objects Export.export(objects, "output.CATPart") # 零件文件 # Export.export(objects, "output.CATProduct") # 装配文件 ``` **操作步骤**: 1. 安装[FreeCAD](https://www.freecad.org/) 2. 将脚本保存为`.py`文件 3. 在FreeCAD的Python控制台中运行: ```python exec(open("your_script.py").read()) ``` **注意**:复杂几何体可能需要手动修复拓扑错误[^1] --- ### ##### 方法2:通过STEP格式中转(工业标准) 使用`ezdxf`读取DXF,通过`occt`库生成STEP文件,再用CATIA转换: ```python # 安装依赖:pip install ezdxf occt from ezdxf import readfile from occt.IFSelect import IFSelect_RetDone from occt.Interface import Interface_Static from occt.STEPControl import STEPControl_Writer # 读取DXF doc = readfile("input.dxf") modelspace = doc.modelspace() # 创建STEP写入器 writer = STEPControl_Writer() Interface_Static.SetCVal("write.step.schema", "AP214") # 遍历DXF实体并转换为STEP(示例:直线) for entity in modelspace: if entity.dxftype() == 'LINE': start = entity.dxf.start end = entity.dxf.end # 在此添加OCCT几何构造代码(需实现实体转换) # 写入STEP文件 if writer.Write("intermediate.step") == IFSelect_RetDone: print("STEP文件生成成功") ``` **后续操作**: 1. 在CATIA中打开STEP文件 2. 另存为.CATPart/.CATProduct格式 3. 可通过CATIA COM接口自动化此过程 --- ### 关键挑战 1. **几何体转换**:DXF的2D图元需转换为CATIA的3D特征 2. **属性映射**:图层、颜色等元数据可能丢失 3. **复杂实体**:NURBS曲面等高级几何需特殊处理 建议优先使用FreeCAD方案,或考虑专业转换工具如[Okino PolyTrans](https://www.okino.com/conv/conv.htm)[^2] ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值