序言

现在代码还在完善中,计划周六先总结,现在现放个思路和原码。

运行效果

运行效果

filedata 类视图

类视图

代码

filedata

unit uDatafile;

interface

uses
        SysUtils, Vcl.Dialogs, System.Classes;

type
        StrArray = array of array of string;

type
        Datafile = class
        private
                FRTotal, FCol, FstartRow: Integer;
                FDataStr: StrArray;
                bufList: Tstringlist;
                function GetCol(s: string): Integer; //返回任意字符串的的列数
                procedure GetDetail(); //获取 数据开始行 数据列数 数据总列数
        public
                constructor Create(filename: string);
                destructor destroy;
                procedure Getdata(readstart: Integer; readend: Integer); //可以读取任意一段的接口
                //属性  都是只读
                property RTotal: Integer read FRTotal;
                property Col: Integer read FCol;
                property StartRow: Integer read FstartRow;
                property Datastr: StrArray read FDataStr;
        end;

implementation

{ Datafile }

constructor Datafile.Create(filename: string);
begin
        FRtotal := 0;
        FCol := 0;
        FstartRow := 0;
        bufList := TStringList.Create;
        bufList.LoadFromFile(filename);
        GetDetail();
        SetLength(FDataStr, FRTotal + 1, FCol);
end;

destructor Datafile.destroy;
begin
        bufList.Free;
end;

function Datafile.GetCol(s: string): Integer;
var
        List: TStringList;
begin
        List := TStringList.Create;
        //这样去判断其实也能精确 但是暂时够用了
        ExtractStrings([';', ',', #9, ' '], [], PChar(s), List); //通过 拆分 list长度来就是字符串的列数
        result := List.Count;
        List.Free;
end;

procedure Datafile.GetDetail;
var
        i, n: Integer;
        s: array[0..2] of string; //用于判断连续的三行
        ss, t1, t2: string;
begin
        i := 0;
        n := 0;
        while i < 200 do
        begin
                //读取连续三行,保存到s 里面
                for n := 0 to 2 do
                begin
                        s[n] := bufList[i + n];
                end;
                //判断连续三行是否相等
                if (GetCol(s[0]) = GetCol(s[1])) and (GetCol(s[0]) = GetCol(s[1])) and (GetCol(s[0]) = GetCol(s[1])) then
                begin
                        ss := Trim(s[0]); //移除左边的空格哇
                        t1 := Copy(ss, 0, 1); //取出第一个字符
                        ss := Trim(s[2]);
                        t2 := Copy(ss, 0, 1);
                        if (t1 >= #48) and (t1 <= #57) and (t2 >= #48) and (t2 <= #57) then //判断他们是不是数字
                        begin
                                Fcol := GetCol(ss); //如果是数那么这段应该是就是数据的开始行
                                Break;
                        end;

                end;
                Inc(i, 1);
        end;
        FstartRow := i + 1; //咱们从零开始计数的 要加1
        Frtotal := bufList.Count - FstartRow;
end;

procedure Datafile.Getdata(readstart, readend: Integer);
var
        lt: TStringList;
        i, n: Integer;
        buf: string;
begin
        if readstart > readend then
                ShowMessage('开始行不能大于结束行')
        else
        begin

                for i := 0 to (readend - readstart) do //我们当然是要循环readend - readstart次
                begin
                        lt := TStringList.Create;
                        buf := bufList[i + readstart + Fstartrow - 1]; //减一的原因还是应为 从0开始计数
                        buf := Trim(buf);
                        if Pos(',', buf) <> 0 then
                                extractstrings([','], [], pchar(buf), lt)
                        else if Pos(';', buf) <> 0 then
                                extractstrings([';'], [], pchar(buf), lt)
                        else if Pos(#9, buf) <> 0 then
                                extractstrings([#9], [], pchar(buf), lt)
                        else
                                extractstrings([' '], [], pchar(buf), lt);
                        if lt.Count <= Fcol then //如果列数发生变化了有可能就是异常数据
                        begin
                                for n := 0 to lt.Count - 1 do
                                begin
                                        buf := lt[n];
                                        FDataStr[i + readstart, n] := buf;
                                        //ShowMessage(FDataStr[i + readstart, n]);
                                end;
                        end;
                        lt.Free;
                end;
        end;
end;

end.

窗口主程序

unit Unit1;

interface

uses
        Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
        System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
        uDatafile, Vcl.Grids, Vcl.ExtCtrls, Vcl.StdCtrls;

type
        TMainForm = class(TForm)
                pnlgrid: TPanel;
                strngrd: TStringGrid;
                grpMmo: TGroupBox;
                Mmo: TMemo;
                pnlPaint: TPanel;
                pbDraw: TPaintBox;
                grpbotton: TGroupBox;
                grpChooseDraw: TGroupBox;
                btnDraw0: TButton;
                grpMouse: TGroupBox;
                btn1: TButton;
                btn2: TButton;
                lbl: TLabel;
                procedure FormCreate(Sender: TObject);
        private
    { Private declarations }
        public
    { Public declarations }
        end;

const
        filename: string = 'data.rec';

var
        MainForm: TMainForm;
        data: Datafile; //打开一个文件 建立一个对象
        Fflag, Dflag: Integer; //分别标记打开文件和画图

procedure Topenfile();//打开文件,如果数据超过5000行那么就多线程打开

function openover(): integer;//判断数据是否读取完毕

procedure Fillgrid();//填充表格

implementation

{$R *.dfm}
procedure TMainForm.FormCreate(Sender: TObject);
begin
        Fflag := 0;
        Dflag := 0;
        data := Datafile.Create(filename);
        TOpenFile();
        if openover() = 4 then
        begin
                //ShowMessage('文件读取完毕');
                strngrd.RowCount := data.RTotal + 3;
                strngrd.ColCount := data.Col + 1;
                strngrd.Cells[0, 0] := '序号';
                strngrd.Cells[1, 0] := '时间 (h)';
                strngrd.Cells[2, 0] := '压力 (MPa)';
                strngrd.Cells[3, 0] := '温度(degC)';
                Fillgrid();
        end;

end;

procedure Topenfile();
var
        total, n: Integer;
begin
        total := data.RTotal;
        if total < 5000 then
        begin
                data.Getdata(0, data.RTotal);
                Fflag := 4;
        end
        else
        begin
                n := total mod 4;
                total := total - n;
                TThread.CreateAnonymousThread(
                        procedure
                        begin
                                data.Getdata(0, total div 4);
                                Fflag := Fflag + 1;
                        end).Start;
                TThread.CreateAnonymousThread(
                        procedure
                        begin
                                data.Getdata(total div 4 + 1, total div 2);
                                Fflag := Fflag + 1;
                        end).Start;
                TThread.CreateAnonymousThread(
                        procedure
                        begin
                                data.Getdata(total div 2 + 1, (total div 4) * 3);
                                Fflag := Fflag + 1;
                        end).Start;
                TThread.CreateAnonymousThread(
                        procedure
                        begin
                                data.Getdata((total div 4) * 3 + 1, total + n);
                                Fflag := Fflag + 1;
                        end).Start;
        end;
end;

function openover(): integer;
begin
        while Fflag <> 4 do
        begin
                ;
        end;
        result := 4;
end;

procedure Fillgrid();
var
        total, n: Integer;
begin
        total := data.RTotal;
        n := total mod 2;
        total := total - n;
        TThread.CreateAnonymousThread(
                procedure
                var i: Integer;
                begin
                        for i := 0 to data.rtotal + n do
                        begin
                                mainform.strngrd.Cells[0, i + 1] := IntToStr(i);
                                mainform.strngrd.Cells[1, i + 1] := data.Datastr[i, 0];
                                mainform.strngrd.Cells[2, i + 1] := data.Datastr[i, 1];
                                mainform.strngrd.cells[3, i + 1] := data.Datastr[i, 2];
                        end;
                end).Start;
end;

end.

努力成长的程序员