论坛首页 海阔天空论坛

要在读取文件的时候给个进度条

浏览 2025 次
精华帖 (0) :: 良好帖 (0) :: 灌水帖 (0) :: 隐藏帖 (1)
作者 正文
   发表时间:2009-07-10   最后修改:2009-07-10

    “要在读取文件的时候添加一个进度条”,在老板看到我做的东西有麽样了以后,一个新的任务就来了。添加进度条的理由是让人在导入的时候能感觉到导入的进度,这样就不容易让使用者感觉不到什么时候完成,什么时候没有完成。
    想想这个功能的确很有用,恩!这个要做,做了感觉上就不一样了。哈哈!这时候突然发现自己的文件读取的地方就根本不在一个单独的类里,于是要把文件的读取专门的提取出来,这样才能让结构更清晰,更合理些。
    经过自己的一整天的努力,终于写成了这样一个文件的读取单元。



unit Unit_DXF_FileRead;

interface

uses
    SysUtils, StrUtils, ComCtrls;

type
    TDXF_FileRead = class
    private
        //文件
        F: Text;
        ReadedFileSize: Integer;
        wordLn1, wordLn2: String;
        Progress: TProgressBar;
        //获取本次读取的dxf 的组码
        function GetCode(): String;
        //获取本次读取的 dxf 的内容
        function GetCont(): String;
        //获取文件的大小
        function GetFileSize(const FileName: String): LongInt;

    public
        //参数分别是  filePath : 传入的文件全路径,  ImportProgressBar: 界面显示进度条。
        constructor Create(filePath: String; ImportProgressBar: TProgressBar);
        destructor Destroy; override;

        //每次读取两行,分别为dxf的组码和内容
        procedure ReadCodeAndCont();
        
        property ReadCode: String read GetCode;
        property ReadCont: String read GetCont;

    end;

implementation

constructor TDXF_FileRead.Create(filePath: String; ImportProgressBar: TProgressBar);
begin
    Progress := ImportProgressBar;
    Progress.Max := GetFileSize(filePath);

    AssignFile(F, filePath);
    Reset(F);

    if (Progress.Max > 20) then
    begin
        Progress.Step := Progress.Max div 20;
    end;
    ReadedFileSize := 0;
end;

destructor TDXF_FileRead.Destroy();
begin

    CloseFile(F);
    Progress := nil;
    inherited Destroy;
end;

function TDXF_FileRead.GetFileSize(const FileName: String): LongInt;
var
    SearchRec: TSearchRec;
begin
    if FindFirst(ExpandFileName(FileName), faAnyFile, SearchRec) = 0 then
        Result := SearchRec.Size
    else
        Result := -1;
end;

procedure TDXF_FileRead.ReadCodeAndCont();
begin
    Readln(F, wordLn1);
    Readln(F, wordLn2);
    Inc(ReadedFileSize, Length(wordln1));
    Inc(ReadedFileSize, Length(wordLn2));
    
    if ((ReadedFileSize div Progress.Step) > 0) then
    begin
        Progress.StepIt();
        Dec(ReadedFileSize, Progress.Step);
    end;

    if (Eof(F)) then
    begin
        wordLn1 := '0';
        wordLn2 := 'EOF';
    end;
end;

    //private
function TDXF_FileRead.GetCode(): String;
begin
    Result := Trim(wordLn1);
end;

function TDXF_FileRead.GetCont(): String;
begin
    Result := Trim(wordLn2);
end;

end.



   诚实而言,GetFileSize函数的实现和关于进度条步进策略都是在网上找到的,感觉都是很好的东西。前两天“师兄”(没有师傅 先这样称呼前来人)看我的这段代码的时候说,你这样做的进度条不精确的,应该在ReadCodeAndCont里用Progress.Position
也就是把

    Inc(ReadedFileSize, Length(wordln1));
    Inc(ReadedFileSize, Length(wordLn2));
    
    if ((ReadedFileSize div Progress.Step) > 0) then
    begin
        Progress.StepIt();
        Dec(ReadedFileSize, Progress.Step);
    end;


换成:

Progress.Position := Progress.Position + Length(wordln1);
Progress.Position := Progress.Position + Length(wordln2);



    他说这样实现的进度条,是非常精确的。想象也是,但是我改过后,看看效果也差不多啊!我决定改回去了,因为我发现速度慢了不少,自己通过比较发现原来4秒钟完成,现在变成了十几秒!我想了一下,在界面上显示的进度条总共才20个格子,而我设定了20步,效果上已经是足够了。我问他们在做导入protel的时候也是这样做的吗?他说是的。我就暗暗想:“难怪这么慢,而且动不动就假死!”。但是他们不会因为我的速度快而去改的,不知道为什么他们老是说不要改,不要改,出问题也是的,再通过一个什么高明的函数,在有问题的地方调用这个函数就是了,整个软件中不知道有多少这样高明的补丁函数了。但是软件还处在没有成熟的阶段
    delphi也是一个很好的面相对象的语言,可惜可以参考的权威的东西实在太少。看到网上说delphi调用类的Destroy的时候,不让直接用.Destroy,而是让用.free()或用FreeAndNil函数。我这样用了,被“师兄”要求改为.Destroy,很不解,但是后来有些明白了,我们的实现里面居然Destroy 都是非override的,虽然都调用了父类的Destroy 。不解中......

论坛首页 海阔天空版

跳转论坛:
Global site tag (gtag.js) - Google Analytics