gpt4 book ai didi

delphi - 在 Delphi 中读取具有固定长度字段和记录的文本文件

转载 作者:行者123 更新时间:2023-12-03 19:35:40 25 4
gpt4 key购买 nike

我需要从字段长度和记录长度固定的文本文件中读取数据。字段要么用零填充,要么用空格填充,总是以相同的顺序出现,每条记录都由 CRLF 终止。该文件可以具有由记录中的第一个字符确定的三种可能的记录类型之一。

到目前为止,我已经为所有记录类型创建了一个基类,并为每个记录类型创建了一个子类。

type
TRecordBase = class abstract
public
// Various common fields...
function ToString: string; virtual; abstract;
procedure Read(AString: string); virtual; abstract;
end;

TRecordType1 = class(TRecordBase)
public
//RecordType1 fields...
function ToString: string; override;
procedure Read(AString: string); override;
end;

TRecordType2 = class(TRecordBase)
public
//RecordType2 fields...
function ToString: string; override;
procedure Read(AString: string); override;
end;

TRecordType3 = class(TRecordBase)
public
//RecordType3 fields...
function ToString: string; override;
procedure Read(AString: string); override;
end;

然后我只需将文件的每一行作为字符串读取,从第一个字符确定其类型,创建适当的类实例并调用 Read .

这个想法是 Record 类可用于读取和写入记录的字符串表示形式。 Read过程需要分解一个字符串并将其分配给公共(public)字段。

我有两个(或三个)问题:
  • 这是处理此类文件的好方法吗?
  • 如果是这样,您将如何实现 Read程序是什么样的? (我处理过分隔文件,但这是我第一次遇到固定长度字段)
  • 如果不是,你会采取什么方法?

  • 更新

    只是想我会填写一些缺失的细节。这些记录类本质上是 DTO(数据传输对象)。这些字段被声明为公共(public)的,唯一的方法是转换成字符串/从字符串转换。对字段的唯一数据验证是编译器的类型检查。使用 TStringBuilder.AppendFormat 将字段按所需顺序转换为字符串.这确保了字段被填充和/或截断到适当的长度。

    我选择了 Rob's使用建议 Copy结合适当的 StrTo*用于从字符串中获取数据。我还将字段位置和长度定义为类常量,即
    const Field1Pos = 1;
    const Field1Length = 1;
    const Field2Pos = 2;
    const Field2Length = 5;

    在对 Copy 的调用中,const 比“魔数(Magic Number)”更容易阅读。 .

    任何其他建议将不胜感激。

    最佳答案

    我会改变一件事:用 Read 构造函数替换读取过程,如下所示:

    TRecordBase = class
    public
    constructor CreateFromText(Text:string);virtual;abstract;
    end;

    TRecordType1 = class(TRecordBase)
    public
    constructor CreateFromText(Text:string);override;
    end;

    根据您对记录的处理方式,这将节省一些输入并使代码更易于阅读:
    var s:string; // string from stream or string-list
    if s[1] = 'X'then DoSomethingWith(TRecordType1.Create(s));

    如果记录类型的数量增加,拥有一个虚拟构造函数也很方便。你可以这样做:
    // Define an class type
    type TRecordBaseClass = class of TRecordBase;

    // Using Delphi 2010? Use a dictionary to register (FirstChar, TRecordBaseClass) paris
    var RecordClassDictionary = TDictionary<char, TRecordBaseClass>;

    // Init the dictionary like this:
    RecordClassDictionary.Add('1', TRecordType1);
    RecordClassDictionary.Add('2', TRecordType2);
    RecordClassDictionary.Add('3', TRecordType3);

    // And use it like this:
    var RecordBaseClass: TRecordBaseClass;
    for line in TextToParse do
    if RecordClassDictionary.TryGetValue(line[1], RecordBaseClass) then
    // Read the record, do something with the record
    DoSomethingWithTheRecord(RecordBaseClass.CreateFromText(line))
    else
    raise Exception.Create('Unkown record type.');

    关于delphi - 在 Delphi 中读取具有固定长度字段和记录的文本文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3204703/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com