# 数据格式处理 **本文档引用的文件** - [Markup.cpp](file://cpp/Tools/Markup.cpp) - [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp) - [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp) - [Res3DDatFile.cpp](file://cpp/Tools/Res3DDatFile.cpp) - [Res3DDatFileRecord.cpp](file://cpp/Tools/Res3DDatFileRecord.cpp) ## 目录 1. [引言](#引言) 2. [XML配置文件解析与生成](#xml配置文件解析与生成) 3. [文本测量数据读写](#文本测量数据读写) 4. [URF专有数据格式解析](#urf专有数据格式解析) 5. [三维测量结果数据存储](#三维测量结果数据存储) 6. [应用实例](#应用实例) 7. [性能优化与错误容忍](#性能优化与错误容忍) 8. [结论](#结论) ## 引言 Geomative Studio项目涉及多种数据格式的处理,包括用于配置的XML文件、用于测量数据交换的文本文件、专有的URF数据格式以及用于存储三维测量结果的二进制DAT文件。本文件详细阐述了`Markup.cpp`、`OperTxtFile.cpp`、`OperUrfFile.cpp`和`Res3DDatFile.cpp`四个核心模块的实现逻辑,分析其在项目缓存、任务脚本导出和结果文件生成中的应用,并讨论其性能优化与错误处理策略。 ## XML配置文件解析与生成 `Markup.cpp`模块提供了一个功能完整的XML文档解析与生成器,其核心是`CMarkup`类。该模块实现了对XML配置文件的节点遍历、属性读取、嵌套结构处理和内存管理。 ### 节点遍历与属性读取 该模块通过维护一个`ElemPos`(元素位置)结构数组来高效地表示XML文档的树形结构。每个`ElemPos`结构记录了节点在文档字符串中的起始位置、长度、标签长度、层级深度以及与其他节点的父子、兄弟关系。这种设计避免了在解析时进行昂贵的字符串分割操作,而是通过索引直接定位节点内容。 对于属性读取,模块提供了`SetAttrib`和`GetAttrib`等方法。当需要设置属性时,它会计算属性在标签字符串中的精确位置,并使用`x_StrInsertReplace`函数进行原地插入或替换,从而最小化内存拷贝开销。 ### 嵌套结构处理 模块通过`iElemParent`、`iElemChild`和`iElemNext`等指针在`ElemPos`结构中构建了完整的树形关系。这使得`FindElem`、`IntoElem`和`OutOfElem`等方法能够高效地在嵌套的XML结构中进行导航。例如,`IntoElem`会将当前上下文移动到当前元素的第一个子元素,而`OutOfElem`则会返回到父元素。 ### 内存管理策略 内存管理是该模块的核心优势。它采用了一种“分段数组”(Segmented Array)的策略来管理`ElemPos`结构。`ElemPosTree`类将`ElemPos`对象存储在多个连续的内存块(段)中,而不是一个巨大的连续数组。这避免了在文档变大时重新分配和复制整个数组的性能瓶颈。`GrowElemPosTree`方法在需要时动态增加新的内存段,确保了在处理大型XML文件时的内存效率和性能稳定性。 **节段来源** - [Markup.cpp](file://cpp/Tools/Markup.cpp#L917-L998) ## 文本测量数据读写 `OperTxtFile.cpp`模块负责处理以文本格式存储的测量数据,支持多种编码和分隔符,主要用于任务脚本和配置的导出。 ### 读写实现 该模块通过标准C库的`fopen`、`fwrite`和`fclose`函数进行文件操作。`OpenFileforWrite`方法以写入模式打开文件,`WriteFileContent`方法则负责将`CStringArray`中的内容写入文件。 ### 编码与分隔符支持 虽然代码中未显式处理编码转换,但通过使用`CString`类,模块天然支持Unicode(UTF-16)和多字节字符集(MBCS)。文件的最终编码取决于系统区域设置和`fopen`函数的内部行为。对于分隔符,该模块采用了一种独特的“固定宽度”格式。`SetParamWidth`方法设置每个字段的固定宽度(默认18个字符),`WriteFileContent`方法会用空格填充不足的字段,从而形成类似表格的对齐效果。这虽然不是传统的逗号或制表符分隔,但提供了一种简单、可读性强的数据格式。 **节段来源** - [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp) ## URF专有数据格式解析 `OperUrfFile.cpp`模块专门用于解析和生成URF(Universal Resistivity File)专有数据格式,这是一种用于地球物理电阻率测量的行业标准文本格式。 ### 解析规则 URF文件采用纯文本格式,包含注释行、元数据行和数据行。该模块的解析规则主要体现在`WriteUrfPoleInfo`和`WriteUrfPoleInfo_3D`等方法中: 1. **头部信息**:通过`WriteUrfHeadInfo`和`Write3DUrfHeadInfo`写入文件描述和单位信息。 2. **几何信息**:以`:Geometry`为分隔符,后跟`ID,X,Y,Z`的列标题,然后是电极的坐标数据。电极坐标的生成逻辑(如温纳装置、偶极装置等)由`WriteElecByAR`系列方法根据不同的测量阵列(AR)类型实现。 3. **测量信息**:以`:Measurements`为分隔符,后跟`A, B, M, N, V/I(ohm), I(mA), Error(%), Chargeability(mV/V)`的列标题,然后是实际的测量数据。 该模块通过`WriteElecByCrossHoleGeomative`等方法从数据库(如`TTaskBindElecInfo`表)中查询电极坐标,实现了URF文件与项目数据的动态绑定。 **节段来源** - [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp) ## 三维测量结果数据存储 `Res3DDatFile.cpp`模块负责将三维测量结果以结构化的二进制布局存储到`.dat`文件中,该文件用于后续的数据处理和成像。 ### 结构化存储机制 #### 二进制布局 该模块使用Windows API的`CreateFile`和`WriteFile`函数直接写入二进制数据。文件布局分为三个部分: 1. **头部**:包含标题、网格列数、行数、列间距、行间距、介质类型和记录点总数。所有数据均以ASCII文本形式写入,每项后跟换行符。 2. **记录数据**:包含多个测量记录。每个记录由A、B、M、N四个电极的坐标(X, Y)和电阻率值`R0`组成。坐标和`R0`均以固定格式的文本写入。 3. **尾部**:写入5个零值,作为文件结束的标记。 #### 元数据嵌入 元数据(如标题、网格尺寸、间距、介质类型)在文件头部以明文形式嵌入。`SetTitle`、`SetGriding`、`SetSpacing`和`SetMedium`等方法用于设置这些元数据。 #### 版本兼容性处理 代码中通过`VAL_ZERO`、`VAL_MINUS_ONE`等常量定义了默认值和无效值,这有助于在不同版本的软件之间保持一定的兼容性。例如,当电极ID为-1时,表示该电极未使用。然而,代码中未发现显式的版本号字段或复杂的向后/向前兼容性逻辑,其兼容性主要依赖于固定的文件结构和数据类型。 **节段来源** - [Res3DDatFile.cpp](file://cpp/Tools/Res3DDatFile.cpp) - [Res3DDatFileRecord.cpp](file://cpp/Tools/Res3DDatFileRecord.cpp) ## 应用实例 上述数据格式处理模块在Geomative Studio中有着广泛的应用: - **项目缓存**:`Markup.cpp`用于读写`CACHE`目录下的`project.xml`和`testzone.xml`文件,保存和恢复项目状态。 - **任务脚本导出**:`OperTxtFile.cpp`用于生成`.map`和`.rul`等脚本文件,`OperUrfFile.cpp`用于将任务导出为标准的URF格式,便于与其他软件交换数据。 - **结果文件生成**:`Res3DDatFile.cpp`用于将三维测量结果生成`.dat`文件,供后续的反演和成像模块使用。 ## 性能优化与错误容忍策略 ### 性能优化 - **内存效率**:`Markup.cpp`的分段数组设计避免了大文件解析时的内存抖动。 - **I/O效率**:`Res3DDatFile.cpp`和`OperUrfFile.cpp`都使用了`fflush`来控制缓冲区刷新,平衡了性能和数据安全性。 - **算法优化**:`Markup.cpp`中的`x_Hash`函数使用了简单的加法哈希,确保了在编码查找时的快速响应。 ### 错误容忍策略 - **输入验证**:所有模块在关键操作前都进行了严格的输入验证,例如检查文件指针是否为空、参数是否在有效范围内。 - **异常处理**:通过`GetLastError()`获取系统错误码,并使用`AfxMessageBox`或`MessageBoxEx`向用户报告详细的错误信息(支持中英文)。 - **资源清理**:在析构函数和`CloseFile`方法中确保文件句柄被正确关闭,防止资源泄漏。 ## 结论 Geomative Studio的数据格式处理体系结构清晰,各模块职责分明。`Markup.cpp`提供了一个高效、内存友好的XML处理方案;`OperTxtFile.cpp`和`OperUrfFile.cpp`分别处理通用文本和行业标准格式;`Res3DDatFile.cpp`则实现了专有的二进制结果存储。这些模块共同支撑了项目的配置管理、数据交换和结果保存功能。尽管在编码转换和版本兼容性方面有进一步提升的空间,但其整体设计稳健,错误处理完善,为地球物理测量软件的可靠运行提供了坚实的基础。