This commit is contained in:
coco
2026-07-03 16:05:30 +08:00
commit df489d5640
1101 changed files with 779140 additions and 0 deletions
@@ -0,0 +1,179 @@
# 数据处理工具
<cite>
**Referenced Files in This Document**
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
- [Crc16.h](file://h/Crc16.h)
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
- [Crc32.h](file://h/Crc32.h)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp)
- [FileOperTools.h](file://h/FileOperTools.h)
- [Markup.cpp](file://cpp/Tools/Markup.cpp)
- [Markup.h](file://h/Markup.h)
- [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp)
- [OperTxtFile.h](file://h/OperTxtFile.h)
- [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp)
- [OperUrfFile.h](file://h/OperUrfFile.h)
- [Res3DDatFile.cpp](file://cpp/Tools/Res3DDatFile.cpp)
- [Res3DDatFile.h](file://h/Res3DDatFile.h)
</cite>
## 目录
1. [引言](#引言)
2. [数据完整性校验工具](#数据完整性校验工具)
3. [文件操作工具](#文件操作工具)
4. [XML配置文件处理](#xml配置文件处理)
5. [特定格式数据文件处理](#特定格式数据文件处理)
6. [三维测量结果数据处理](#三维测量结果数据处理)
7. [应用场景与使用示例](#应用场景与使用示例)
8. [内存管理与性能优化](#内存管理与性能优化)
9. [错误恢复策略](#错误恢复策略)
10. [结论](#结论)
## 引言
GeomativeStudio中的数据处理工具集为地质勘探数据的完整性校验、文件操作、配置管理及数据存储提供了全面的解决方案。这些工具在项目配置保存、测量数据导出和缓存管理等关键场景中发挥着重要作用。本文档将深入解析Crc16.cpp和Crc32.cpp实现的数据完整性校验机制,FileOperTools.cpp封装的文件操作接口,Markup.cpp对XML配置文件的解析与生成逻辑,以及OperTxtFile.cpp、OperUrfFile.cpp和Res3DDatFile.cpp对特定格式数据文件的读写实现。
## 数据完整性校验工具
### CRC16校验实现
Crc16类实现了基于查表法的CRC16校验算法,通过预计算的256项查找表优化性能。该类采用静态成员变量`table`存储预计算的校验值,并使用`initialized`标志确保表只初始化一次。构造函数接收初始值,通过位运算和多项式0x1021进行校验计算。`update`方法对每个输入字节进行处理,利用查表法快速更新校验值,避免了重复的多项式除法运算。
**Section sources**
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp#L28-L54)
- [Crc16.h](file://h/Crc16.h#L12-L37)
### CRC32校验实现
Crc32类实现了CRC32校验算法,同样采用查表优化技术。与CRC16类似,它使用静态`table`数组存储预计算值,并通过`initialized`标志控制初始化。构造函数使用多项式0xEDB88320L进行表的生成,该多项式是CRC32标准算法的核心。`update`方法通过查表和位移操作高效更新校验值,确保数据完整性验证的高性能。
**Section sources**
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp#L28-L51)
- [Crc32.h](file://h/Crc32.h#L12-L37)
## 文件操作工具
### 文件操作接口封装
CFileOperTools类封装了常用的文件操作功能,提供了一个单例模式的全局访问点。该类实现了目录复制、文件存在性检查、文件删除、日志写入等核心功能。`CopyFolder`方法递归复制目录及其内容,`DeleteDirectory`方法递归删除目录树,确保了文件系统操作的完整性和可靠性。
**Section sources**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L58-L124)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L261-L323)
- [FileOperTools.h](file://h/FileOperTools.h#L12-L42)
### 文件锁定与日志机制
该工具类实现了线程安全的日志写入机制,使用临界区(CRITICAL_SECTION)保护日志文件的并发访问。`WriteComLog`方法在写入日志前获取临界区锁,确保多线程环境下的数据一致性。同时,类提供了`CloseComLog`方法正确释放资源,防止内存泄漏。`DealGeneralLogFunc`方法创建后台线程定期清理过期日志文件,实现了自动化的日志管理。
**Section sources**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L21-L37)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L150-L197)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L345-L398)
## XML配置文件处理
### XML解析与生成逻辑
CMarkup类提供了完整的XML文档处理能力,支持文档加载、元素查找、属性读取、内容修改等操作。该类采用内部状态机解析XML文档,通过`FindElem`方法定位元素,`GetAttrib``GetData`方法提取属性和内容。`AddElem``SetData`方法允许动态修改文档结构,支持创建和更新XML配置文件。
**Section sources**
- [Markup.cpp](file://cpp/Tools/Markup.cpp#L265-L291)
- [Markup.h](file://h/Markup.h#L276-L305)
### 编码转换与字符处理
CMarkup类内置了强大的编码转换功能,支持UTF-8、UTF-16、UTF-32等多种编码格式的相互转换。通过`TextEncoding`结构体和相关方法,实现了跨平台的字符集处理。`x_GetEncodingCodePage`函数使用哈希表快速查找编码对应的代码页,`PerformConversion`方法执行实际的编码转换,确保XML文档在不同环境下的正确读写。
**Section sources**
- [Markup.cpp](file://cpp/Tools/Markup.cpp#L183-L764)
- [Markup.h](file://h/Markup.h#L387-L394)
## 特定格式数据文件处理
### 文本文件操作
COperTxtFile类专门处理文本文件的读写操作,提供了参数化宽度的文本写入功能。`SetParamWidth`方法设置输出字段宽度,`WriteFileContent`方法将字符串数组按指定宽度格式化写入文件,不足部分用空格填充。该类还实现了错误检查和日志记录,确保文件操作的可靠性和可追溯性。
**Section sources**
- [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp#L39-L57)
- [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp#L104-L158)
- [OperTxtFile.h](file://h/OperTxtFile.h#L12-L32)
### URF文件处理
COperUrfFile类负责URFUniversal Resistivity data File)格式文件的生成,支持多种电极阵列配置。该类提供了`WriteElecByAR`系列方法,根据不同的装置类型(如温纳-施伦贝格尔、跨孔等)生成相应的电极坐标信息。`WriteUrfHeadInfo`方法创建文件头,包含格式说明和单位信息,确保文件的标准化和可读性。
**Section sources**
- [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp#L64-L77)
- [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp#L506-L538)
- [OperUrfFile.h](file://h/OperUrfFile.h#L12-L52)
## 三维测量结果数据处理
### 三维数据文件结构
CRes3DDatFile类处理三维测量结果数据的结构化存储,采用特定的二进制文件格式。该类定义了文件头、记录和文件尾三部分结构,通过`WriteHead``WriteRecord``WriteTail`方法分别写入。文件头包含标题、网格尺寸、间距和介质类型等元数据,记录部分存储具体的测量点数据。
**Section sources**
- [Res3DDatFile.cpp](file://cpp/Tools/Res3DDatFile.cpp#L189-L257)
- [Res3DDatFile.cpp](file://cpp/Tools/Res3DDatFile.cpp#L260-L322)
- [Res3DDatFile.cpp](file://cpp/Tools/Res3DDatFile.cpp#L325-L351)
- [Res3DDatFile.h](file://h/Res3DDatFile.h#L28-L31)
### 数据记录管理
该类使用CPtrArray管理测量记录,通过`AddRecord`方法添加新的测量点,`DelRecord``ClearAllRecord`方法删除记录。`Generate`方法协调整个文件生成过程,先创建文件,然后依次写入头部、记录和尾部信息。`SetMedium`方法将用户友好的介质代码转换为内部表示,确保数据的一致性和正确性。
**Section sources**
- [Res3DDatFile.cpp](file://cpp/Tools/Res3DDatFile.cpp#L100-L165)
- [Res3DDatFile.cpp](file://cpp/Tools/Res3DDatFile.cpp#L353-L386)
- [Res3DDatFile.cpp](file://cpp/Tools/Res3DDatFile.cpp#L168-L187)
## 应用场景与使用示例
### 项目配置保存
在项目配置保存场景中,Markup类用于序列化应用程序设置到XML文件。通过`SetDoc`方法加载现有配置或创建新文档,使用`AddElem``AddAttrib`方法添加配置项,最后调用`Save`方法持久化到磁盘。这种机制确保了配置数据的结构化存储和跨会话持久性。
**Section sources**
- [Markup.cpp](file://cpp/Tools/Markup.cpp#L344-L346)
- [Markup.cpp](file://cpp/Tools/Markup.cpp#L346-L348)
### 测量数据导出
测量数据导出功能结合使用OperTxtFile和OperUrfFile类,将采集的测量结果转换为标准格式。对于文本报告,使用OperTxtFile按固定宽度格式化输出;对于专业分析,使用OperUrfFile生成URF格式文件,包含电极配置和测量数据。这种多格式支持满足了不同用户和软件的需求。
**Section sources**
- [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp#L104-L158)
- [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp#L506-L538)
### 缓存管理
缓存管理利用FileOperTools类的目录操作功能,实现缓存文件的自动清理。`DealGeneralLogThread`方法扫描日志目录,识别并删除两天前的旧文件,防止磁盘空间耗尽。`CopyFolder``DeleteDirectory`方法支持缓存的备份和重置,确保系统稳定运行。
**Section sources**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L346-L398)
## 内存管理与性能优化
### 查表法优化
CRC校验算法采用查表法进行性能优化,将复杂的多项式除法运算转换为简单的查表操作。Crc16和Crc32类在首次使用时预计算256个可能的余数,存储在静态数组中。后续计算只需一次查表和几次位运算,大大提高了处理速度,特别适合处理大量数据的场景。
**Section sources**
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp#L38-L50)
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp#L38-L47)
### 资源管理
所有文件操作类都实现了正确的资源管理,确保文件句柄和内存的及时释放。析构函数中调用`CloseFile``CloseComLog`关闭文件,`ClearAllRecord`方法释放动态分配的记录对象。这种RAII(资源获取即初始化)模式防止了资源泄漏,提高了系统的稳定性和可靠性。
**Section sources**
- [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp#L27-L35)
- [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp#L26-L29)
- [Res3DDatFile.cpp](file://cpp/Tools/Res3DDatFile.cpp#L35-L36)
## 错误恢复策略
### 异常处理与日志记录
数据处理工具集实现了全面的错误检测和恢复机制。每个关键操作都包含输入验证和边界检查,如`OpenFileforWrite`检查文件名是否为空。操作失败时,通过`WriteComLog`记录详细的错误信息,包括错误码和上下文,便于问题诊断和恢复。
**Section sources**
- [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp#L69-L97)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L150-L197)
### 事务性操作
对于复杂的文件操作,如目录复制和删除,采用事务性设计原则。操作过程中持续检查状态,一旦发现错误立即停止并记录,避免部分完成的状态。`CopyFolder`方法在复制每个文件前检查源和目标路径,`DeleteDirectory`方法在删除每个子项前验证其存在性,确保操作的原子性和一致性。
**Section sources**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L58-L124)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L261-L323)
## 结论
GeomativeStudio的数据处理工具集通过精心设计的类和方法,提供了高效、可靠的数据完整性校验、文件操作和数据存储功能。CRC校验工具采用查表法优化性能,文件操作工具确保线程安全和资源正确管理,XML处理工具支持复杂的配置管理,特定格式文件处理工具满足专业数据交换需求。这些工具协同工作,为地质勘探应用提供了坚实的数据处理基础,确保了数据的完整性、一致性和可追溯性。
@@ -0,0 +1,204 @@
# 数据校验工具
<cite>
**本文档引用的文件**
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp)
- [Crc16.h](file://h/Crc16.h)
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp)
- [Crc32.h](file://h/Crc32.h)
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp)
</cite>
## 目录
1. [引言](#引言)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构概述](#架构概述)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
## 引言
本文档深入解析GeomativeStudio中实现的数据完整性校验机制,重点分析CRC16和CRC32算法的具体实现方式。文档详细说明了标准多项式选择、查表法优化策略、字节序处理及内存对齐优化等关键技术,并阐述这些校验工具在设备通信协议数据包、配置文件传输和测量数据存储中的应用场景。
## 项目结构
GeomativeStudio项目中的CRC校验工具位于cpp/Tools目录下,包含Crc16.cpp和Crc32.cpp两个核心实现文件,以及对应的头文件Crc16.h和Crc32.h。这些工具被集成在Zmodem文件传输协议中,用于确保数据传输的完整性。
```mermaid
graph TD
A[CRC校验工具] --> B[Crc16.cpp]
A --> C[Crc32.cpp]
A --> D[Crc16.h]
A --> E[Crc32.h]
B --> F[Zmodem.cpp]
C --> F
F --> G[文件传输]
F --> H[数据通信]
```
**图示来源**
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp#L1-L54)
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp#L1-L51)
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp#L1-L1940)
**章节来源**
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp#L1-L54)
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp#L1-L51)
## 核心组件
CRC16和CRC32类实现了数据完整性校验的核心功能。Crc16类使用16位循环冗余校验,而Crc32类使用32位循环冗余校验。两个类都采用了查表法优化策略,通过预计算的CRC表来提高计算效率。
**章节来源**
- [Crc16.h](file://h/Crc16.h#L1-L37)
- [Crc32.h](file://h/Crc32.h#L1-L37)
## 架构概述
CRC校验工具的架构设计采用了静态查表法,通过预计算的CRC表来加速校验计算过程。初始化时生成CRC表,后续计算直接查表获取结果,大大提高了计算效率。该架构被设计为轻量级工具类,可被多个模块复用。
```mermaid
classDiagram
class Crc16 {
+static unsigned short table[256]
+static int initialized
-unsigned short crc
+Crc16(unsigned short init_value)
+void update(int c)
+unsigned short value()
}
class Crc32 {
+static unsigned long table[256]
+static int initialized
-unsigned long crc
+Crc32(unsigned long init_value)
+void update(int c)
+unsigned long value()
}
Crc16 <|-- Crc32 : 继承自
```
**图示来源**
- [Crc16.h](file://h/Crc16.h#L12-L27)
- [Crc32.h](file://h/Crc32.h#L12-L28)
## 详细组件分析
### CRC16组件分析
CRC16类实现了16位循环冗余校验算法,采用CCITT标准多项式x^16 + x^12 + x^5 + 10x1021)。该实现使用查表法优化,通过预计算256个字节的CRC值来加速计算过程。
#### CRC16类图
```mermaid
classDiagram
class Crc16 {
+static unsigned short table[256]
+static int initialized
-unsigned short crc
+Crc16(unsigned short init_value)
+void update(int c)
+unsigned short value()
}
```
**图示来源**
- [Crc16.h](file://h/Crc16.h#L12-L27)
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp#L28-L54)
### CRC32组件分析
CRC32类实现了32位循环冗余校验算法,采用IEEE 802.3标准多项式x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x + 10xEDB88320)。与CRC16类似,也采用了查表法优化策略。
#### CRC32类图
```mermaid
classDiagram
class Crc32 {
+static unsigned long table[256]
+static int initialized
-unsigned long crc
+Crc32(unsigned long init_value)
+void update(int c)
+unsigned long value()
}
```
**图示来源**
- [Crc32.h](file://h/Crc32.h#L12-L28)
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp#L28-L51)
### 实际应用分析
CRC校验工具在Zmodem文件传输协议中得到了广泛应用,用于确保数据传输的完整性。在文件传输过程中,发送方计算数据的CRC值并随数据一起发送,接收方重新计算CRC值进行比对,以检测传输过程中的任何数据损坏。
#### Zmodem协议中的CRC使用流程
```mermaid
sequenceDiagram
participant 发送方
participant 接收方
发送方->>发送方 : 初始化CRC32(0xFFFFFFFFL)
发送方->>发送方 : 计算数据CRC值
发送方->>接收方 : 发送数据和CRC校验码
接收方->>接收方 : 初始化CRC32(0xFFFFFFFFL)
接收方->>接收方 : 计算接收到数据的CRC值
接收方->>接收方 : 比对CRC值
alt CRC匹配
接收方->>发送方 : 发送确认
else CRC不匹配
接收方->>发送方 : 请求重传
end
```
**图示来源**
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp#L797-L820)
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp#L1643-L1670)
**章节来源**
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp#L790-L890)
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp#L1640-L1700)
## 依赖分析
CRC校验工具作为独立的工具类,被Zmodem文件传输模块所依赖。这种设计实现了关注点分离,使得CRC校验功能可以被多个模块复用,同时保持了代码的可维护性和可测试性。
```mermaid
graph TD
A[Zmodem.cpp] --> B[Crc16.cpp]
A --> C[Crc32.cpp]
B --> D[Crc16.h]
C --> E[Crc32.h]
```
**图示来源**
- [Zmodem.cpp](file://cpp/Tools/Zmodem.cpp#L5-L6)
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp#L5-L6)
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp#L5-L6)
## 性能考虑
CRC校验工具的性能优化主要体现在以下几个方面:
1. 查表法:通过预计算CRC表,将复杂的多项式除法运算转换为简单的查表操作
2. 静态初始化:CRC表只在首次使用时生成,避免重复计算
3. 内联函数:update方法被定义为内联函数,减少函数调用开销
4. 位运算优化:使用位移和异或操作替代乘除法运算
这些优化策略使得CRC计算具有很高的效率,适合在高频率数据传输场景中使用。
## 故障排除指南
在使用CRC校验工具时,可能遇到以下常见问题及解决方案:
1. **CRC计算结果不一致**
- 检查初始化值是否一致
- 确认多项式标准是否匹配
- 验证字节序处理是否正确
2. **性能瓶颈**
- 确认CRC表已正确初始化
- 检查是否重复创建CRC对象
- 考虑批量处理数据以减少对象创建开销
3. **内存问题**
- CRC表占用256*sizeof(unsigned short)或256*sizeof(unsigned long)内存
- 确保有足够的内存空间
**章节来源**
- [Crc16.cpp](file://cpp/Tools/Crc16.cpp#L33-L52)
- [Crc32.cpp](file://cpp/Tools/Crc32.cpp#L33-L49)
## 结论
GeomativeStudio中的CRC校验工具实现了高效可靠的数据完整性校验机制。通过采用查表法优化和合理的架构设计,这些工具在保证计算准确性的同时,提供了优异的性能表现。在设备通信协议数据包、配置文件传输和测量数据存储等场景中,CRC校验有效防止了数据损坏,确保了系统的可靠运行。建议在高并发或大文件处理场景中复用CRC对象,以进一步优化性能。
@@ -0,0 +1,121 @@
# 数据格式处理
<cite>
**本文档引用的文件**
- [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)
</cite>
## 目录
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`模块专门用于解析和生成URFUniversal 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`则实现了专有的二进制结果存储。这些模块共同支撑了项目的配置管理、数据交换和结果保存功能。尽管在编码转换和版本兼容性方面有进一步提升的空间,但其整体设计稳健,错误处理完善,为地球物理测量软件的可靠运行提供了坚实的基础。
@@ -0,0 +1,274 @@
# 文件操作封装
<cite>
**本文档引用的文件**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp)
- [FileOperTools.h](file://h/FileOperTools.h)
- [MyCopyFile.cpp](file://cpp/Tools/MyCopyFile.cpp)
- [MyCopyFile.h](file://h/MyCopyFile.h)
- [AutoLock.cpp](file://cpp/Lock/AutoLock.cpp)
- [AutoLock.h](file://h/Lock/AutoLock.h)
- [RingBuffer.h](file://h/RingBuffer.h)
</cite>
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构概述](#架构概述)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排除指南](#故障排除指南)
9. [结论](#结论)
## 简介
本文档全面解析`FileOperTools.cpp``MyCopyFile.cpp`中封装的文件系统操作功能。重点描述跨平台路径处理(支持Windows风格路径)、目录创建与遍历、文件锁定机制、原子性文件写入、大文件复制优化(缓冲区管理、异步I/O)等关键技术实现。说明这些工具类在项目配置保存、缓存管理、日志写入和数据导出等场景中的使用模式。提供接口调用示例,包括错误码处理、权限异常恢复和磁盘空间预检等最佳实践。分析其与MFC CFile类的差异与优势,以及在多线程环境下的线程安全设计。
## 项目结构
项目包含多个核心目录,其中`cpp/Tools`目录下存放了文件操作相关的工具类实现。`FileOperTools.cpp``MyCopyFile.cpp`位于此目录,分别提供基础文件操作和高级文件复制功能。`h/`目录下有对应的头文件声明。项目还包含日志管理、锁机制等辅助组件,支持文件操作的完整功能实现。
```mermaid
graph TD
subgraph "核心工具"
FileOperTools["FileOperTools.cpp<br/>基础文件操作"]
MyCopyFile["MyCopyFile.cpp<br/>高级文件复制"]
end
subgraph "辅助组件"
AutoLock["AutoLock.cpp<br/>自动锁机制"]
RingBuffer["RingBuffer.h<br/>环形缓冲区"]
end
subgraph "日志系统"
Log["日志文件<br/>(log\\general\\*.txt)"]
end
FileOperTools --> Log
MyCopyFile --> Log
FileOperTools --> AutoLock
MyCopyFile --> AutoLock
```
**图示来源**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L1-L420)
- [MyCopyFile.cpp](file://cpp/Tools/MyCopyFile.cpp#L1-L155)
- [AutoLock.cpp](file://cpp/Lock/AutoLock.cpp#L1-L12)
**本节来源**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L1-L420)
- [MyCopyFile.cpp](file://cpp/Tools/MyCopyFile.cpp#L1-L155)
## 核心组件
`FileOperTools`类提供基础文件操作功能,包括目录复制、文件存在性检查、文件删除、日志写入等。`MyCopyFile`类专注于大文件的高效复制,支持进度监控和传输中断处理。两个类都采用单例模式或静态成员实现,确保全局访问的一致性。通过临界区(CRITICAL_SECTION)实现线程安全的日志写入,避免多线程环境下的数据竞争。
**本节来源**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L1-L420)
- [MyCopyFile.cpp](file://cpp/Tools/MyCopyFile.cpp#L1-L155)
- [FileOperTools.h](file://h/FileOperTools.h#L1-L42)
- [MyCopyFile.h](file://h/MyCopyFile.h#L1-L48)
## 架构概述
文件操作工具采用分层架构设计,上层为功能接口,中层为业务逻辑,底层为系统API调用。`FileOperTools`负责通用文件操作,`MyCopyFile`专注于文件传输场景。两者共享日志系统和线程安全机制。通过`AutoLock`类实现RAII风格的锁管理,确保异常安全的资源释放。
```mermaid
graph TB
subgraph "接口层"
A["CopyFolder"]
B["IsFileExist"]
C["DeleteDirectory"]
D["TransferFile"]
E["GetTransferInfo"]
end
subgraph "逻辑层"
F["FileOperTools"]
G["MyCopyFile"]
end
subgraph "安全层"
H["CRITICAL_SECTION"]
I["AutoLock"]
end
subgraph "系统层"
J["Windows API"]
K["KERNEL32"]
end
A --> F
B --> F
C --> F
D --> G
E --> G
F --> H
G --> H
H --> I
F --> J
G --> J
J --> K
```
**图示来源**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L1-L420)
- [MyCopyFile.cpp](file://cpp/Tools/MyCopyFile.cpp#L1-L155)
- [AutoLock.cpp](file://cpp/Lock/AutoLock.cpp#L1-L12)
## 详细组件分析
### FileOperTools 分析
`CFileOperTools`类实现了一个单例模式的文件操作工具,提供目录复制、文件删除、日志管理等功能。通过`GetInstance()`方法获取唯一实例,确保全局状态的一致性。类中使用临界区保护日志文件的并发写入,避免多线程环境下的数据损坏。
#### 类图
```mermaid
classDiagram
class CFileOperTools {
+CFileOperTools()
+~CFileOperTools()
+static CFileOperTools* GetInstance()
+bool CopyFolder(CString strSrcPath, CString strDstPath)
+bool IsFileExist(CString strFileInfo)
+bool WriteComLog(const CString& strInfo)
+bool WriteComLog(unsigned char *pszData, int iDateLen)
+bool DeleteDirectory(CString strDirPath)
+bool DeleteFileDirect(CString strFilePath)
+CString GetDstFilePathFolder()
+bool GeneralLogName()
+bool DealGeneralLogFunc()
-void CloseComLog()
-static UINT DealGeneralLogThread(LPVOID lParam)
-static CFileOperTools* m_pFileOper
-FILE* m_pComLog
-CRITICAL_SECTION *m_pWriteLogSection
-CString m_strGeneralLogName
}
```
**图示来源**
- [FileOperTools.h](file://h/FileOperTools.h#L11-L42)
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L1-L420)
#### 目录复制流程
```mermaid
flowchart TD
Start([开始复制目录]) --> CheckPath["检查源路径和目标路径"]
CheckPath --> PathValid{"路径有效?"}
PathValid --> |否| ReturnError["返回错误"]
PathValid --> |是| RemoveTrailing["移除路径末尾反斜杠"]
RemoveTrailing --> CreateDir["创建目标目录"]
CreateDir --> FindFiles["查找源目录文件"]
FindFiles --> HasNext{"有更多文件?"}
HasNext --> |否| ReturnSuccess["返回成功"]
HasNext --> |是| GetNextFile["获取下一个文件"]
GetNextFile --> IsDot{"是.或..?"}
IsDot --> |是| FindFiles
IsDot --> |否| IsDir{"是目录?"}
IsDir --> |是| RecursiveCopy["递归复制子目录"]
RecursiveCopy --> FindFiles
IsDir --> |否| CopyFile["复制文件"]
CopyFile --> CheckError{"复制失败?"}
CheckError --> |是| LogError["记录错误并返回"]
CheckError --> |否| FindFiles
```
**图示来源**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L58-L124)
**本节来源**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L1-L420)
- [FileOperTools.h](file://h/FileOperTools.h#L1-L42)
### MyCopyFile 分析
`CMyCopyFile`类专注于大文件的高效、可靠传输。利用Windows API的`CopyFileEx`函数实现带进度回调的文件复制,支持传输过程中的取消操作。通过静态成员变量实现全局日志管理,确保传输日志的集中记录。
#### 类图
```mermaid
classDiagram
class CMyCopyFile {
+CMyCopyFile()
+~CMyCopyFile()
+bool TransferFile(CString strSrcDir, CString strDstDir, CString strFileName)
+void GetTransferInfo(DWORD &dwTransferedBytes, DWORD &dwTotalFileSize)
+int GetTansferLastError()
+void Initialize()
-void PrintLog(const CString& strLog)
-static DWORD CALLBACK CopyProgressInfo(LARGE_INTEGER, LARGE_INTEGER, ...)
-static FILE* g_pCopyFileLog
-static CRITICAL_SECTION* g_pLogCriticSec
-LARGE_INTEGER m_liTransferedBytes
-LARGE_INTEGER m_liTotalFileSize
-int m_iErrorCode
-BOOL m_bIsCancelCopy
}
```
**图示来源**
- [MyCopyFile.h](file://h/MyCopyFile.h#L18-L48)
- [MyCopyFile.cpp](file://cpp/Tools/MyCopyFile.cpp#L1-L155)
#### 文件传输流程
```mermaid
sequenceDiagram
participant Client as "客户端"
participant MyCopyFile as "CMyCopyFile"
participant OS as "操作系统"
Client->>MyCopyFile : TransferFile(参数)
MyCopyFile->>MyCopyFile : 检查源文件属性
MyCopyFile->>MyCopyFile : 删除目标文件
MyCopyFile->>OS : CopyFileEx(带进度回调)
loop 进度更新
OS->>MyCopyFile : 调用CopyProgressInfo
MyCopyFile->>MyCopyFile : 更新传输进度
MyCopyFile->>MyCopyFile : 检查设备连接状态
MyCopyFile->>MyCopyFile : 记录日志
MyCopyFile-->>OS : 返回PROGRESS_CONTINUE
end
OS-->>MyCopyFile : 复制完成
MyCopyFile-->>Client : 返回结果
```
**图示来源**
- [MyCopyFile.cpp](file://cpp/Tools/MyCopyFile.cpp#L76-L107)
- [MyCopyFile.cpp](file://cpp/Tools/MyCopyFile.cpp#L137-L154)
**本节来源**
- [MyCopyFile.cpp](file://cpp/Tools/MyCopyFile.cpp#L1-L155)
- [MyCopyFile.h](file://h/MyCopyFile.h#L1-L48)
## 依赖分析
文件操作工具依赖于Windows API进行底层文件操作,使用MFC的CString类处理字符串。通过临界区实现线程同步,依赖系统时间函数获取时间戳。`MyCopyFile`类还依赖`DetcGD10Dev`类检测设备连接状态,实现智能传输中断。
```mermaid
graph LR
FileOperTools --> WindowsAPI
MyCopyFile --> WindowsAPI
FileOperTools --> MFC
MyCopyFile --> MFC
FileOperTools --> AutoLock
MyCopyFile --> AutoLock
MyCopyFile --> DetcGD10Dev
AutoLock --> WindowsAPI
subgraph "外部依赖"
WindowsAPI["Windows API"]
MFC["MFC框架"]
end
subgraph "内部依赖"
DetcGD10Dev["DetcGD10Dev.cpp"]
end
```
**图示来源**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L5-L420)
- [MyCopyFile.cpp](file://cpp/Tools/MyCopyFile.cpp#L5-L155)
- [AutoLock.cpp](file://cpp/Lock/AutoLock.cpp#L1-L12)
**本节来源**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L1-L420)
- [MyCopyFile.cpp](file://cpp/Tools/MyCopyFile.cpp#L1-L155)
- [AutoLock.cpp](file://cpp/Lock/AutoLock.cpp#L1-L12)
## 性能考虑
文件操作工具在设计时考虑了性能优化。`CopyFolder`方法采用递归方式遍历目录,对于大型目录树可能产生较深的调用栈。`MyCopyFile`使用`CopyFileEx` API,该API内部实现了高效的缓冲区管理和异步I/O,适合大文件传输。日志系统通过临界区保护,但频繁的日志写入可能成为性能瓶颈。建议在生产环境中合理控制日志级别。
## 故障排除指南
常见问题包括文件访问权限不足、磁盘空间不足、路径过长等。`FileOperTools`在操作失败时会记录详细的错误码,可通过`GetLastError()`获取具体原因。`MyCopyFile`提供`GetTansferLastError()`方法获取传输错误码。当遇到"临界区创建失败"错误时,可能是系统资源不足。建议检查磁盘空间、文件权限和系统资源使用情况。
**本节来源**
- [FileOperTools.cpp](file://cpp/Tools/FileOperTools.cpp#L1-L420)
- [MyCopyFile.cpp](file://cpp/Tools/MyCopyFile.cpp#L1-L155)
## 结论
`FileOperTools``MyCopyFile`提供了完整的文件系统操作解决方案。前者侧重于通用文件操作,后者专注于大文件传输场景。两者都实现了线程安全的日志记录,通过临界区保护共享资源。与MFC CFile类相比,这些工具类提供了更高层次的抽象和更丰富的功能,特别是在目录操作和进度监控方面。在多线程环境下,通过RAII风格的`AutoLock`类确保了资源管理的安全性。