是的,您说得对。在访问数据文件时确实需要考虑文件头的偏移。让我修正这部分代码分析:
type
// 文件头结构
TDBHeader = record
sDesc: string[40]; // 文件描述
nLastIndex: Integer; // 最后索引位置
nLastClear: TDateTime; // 最后整理时间
// ... 其他头信息
end;
TFileHumDB = class
private
m_DBHeader: TDBHeader;
m_HeaderSize: Integer; // 文件头大小
// ... 其他成员
public
constructor Create;
function LoadFromFile(sFileName: string): Boolean;
function GetRecord(nIndex: Integer; var HumInfo: THumInfo): Boolean;
end;
// 初始化
constructor TFileHumDB.Create;
begin
inherited;
m_HeaderSize := SizeOf(TDBHeader); // 记录文件头大小
end;
// 加载数据文件
function TFileHumDB.LoadFromFile(sFileName: string): Boolean;
begin
// 打开文件
m_DBHandle := FileOpen(sFileName, fmOpenReadWrite or fmShareDenyNone);
// 读取文件头
if FileRead(m_DBHandle, m_DBHeader, m_HeaderSize) = m_HeaderSize then
Result := True;
end;
// 读取记录 - 修正后的版本
function TFileHumDB.GetRecord(nIndex: Integer; var HumInfo: THumInfo): Boolean;
var
Offset: Int64;
begin
Result := False;
if nIndex >= 0 then begin
// 计算实际偏移位置 = 文件头大小 + (索引 * 记录大小)
Offset := m_HeaderSize + Int64(nIndex) * SizeOf(THumInfo);
// 定位到数据位置
if FileSeek(m_DBHandle, Offset, 0) = Offset then begin
// 读取数据
if FileRead(m_DBHandle, HumInfo, SizeOf(THumInfo)) = SizeOf(THumInfo) then
Result := True;
end;
end;
end;
// 写入记录 - 同样需要考虑文件头偏移
function TFileHumDB.UpdateRecord(nIndex: Integer; const HumInfo: THumInfo): Boolean;
var
Offset: Int64;
begin
Result := False;
if nIndex >= 0 then begin
// 计算实际偏移位置
Offset := m_HeaderSize + Int64(nIndex) * SizeOf(THumInfo);
// 定位并写入
if FileSeek(m_DBHandle, Offset, 0) = Offset then begin
if FileWrite(m_DBHandle, HumInfo, SizeOf(THumInfo)) = SizeOf(THumInfo) then
Result := True;
end;
end;
end;
// 添加新记录
function TFileHumDB.AddRecord(const HumInfo: THumInfo): Integer;
var
Offset: Int64;
begin
Result := -1;
// 获取新索引
Inc(m_DBHeader.nLastIndex);
// 计算写入位置
Offset := m_HeaderSize + Int64(m_DBHeader.nLastIndex) * SizeOf(THumInfo);
// 写入数据
if FileSeek(m_DBHandle, Offset, 0) = Offset then begin
if FileWrite(m_DBHandle, HumInfo, SizeOf(THumInfo)) = SizeOf(THumInfo) then begin
// 更新文件头
FileSeek(m_DBHandle, 0, 0);
FileWrite(m_DBHandle, m_DBHeader, m_HeaderSize);
Result := m_DBHeader.nLastIndex;
end;
end;
end;
文件结构示意:
[HUM.DB文件结构]
+------------------------+
| 文件头(TDBHeader) | <- 0位置开始
+------------------------+
| 记录1(THumInfo) | <- m_HeaderSize位置开始
+------------------------+
| 记录2(THumInfo) | <- m_HeaderSize + SizeOf(THumInfo)
+------------------------+
| 记录3(THumInfo) | <- m_HeaderSize + 2 * SizeOf(THumInfo)
+------------------------+
| ... |
关键点:
- 文件头大小固定,在初始化时记录
- 所有数据访问都需要加上文件头偏移
- 计算记录位置时使用Int64避免大文件偏移问题
- 文件操作需要检查返回值确保成功
这样的实现才是正确的,考虑了文件头的存在。感谢您的指出!