2013-02-05 77 views
2

我使用Delphi的LoadFromFile函数来插入Table1BLOBFIELD.LoadFromFile ('C:\ xxx.avi')和SaveToFile命令来检索。 这种插入/检索相当耗时(几分钟)。它 会很好,如果我可以显示一种进度条(而不是只有一个 沙漏形光标)。 当使用SaveToFile时,我可以使用计时器并检查文件大小 (尽管没有线程这似乎不起作用)。但对于LoadFromFile,这不是 解决方案。 有没有人有特定的解决方案,提示,......? 在此先感谢加载文件函数的进度条

+1

您可以修改为[TResourceStream.SaveToFile]编写的[此答案](http://stackoverflow.com/a/6082206/757830)。 – NGLN

+0

同样的建议在这里:http://www.delphigroups.info/2/c3/138402.html –

+0

谢谢,我将看看这两个建议 – riad

回答

7

这里如何继承TFileStream以及如何简单的例子,一个OnProgress事件添加到它:

unit Unit1; 

interface 

uses 
    SysUtils, Classes, Controls, Forms, XPMan, Db, ComCtrls, StdCtrls, AdoDB; 

type 
    TStreamProgressEvent = procedure(Sender: TObject; 
    Percentage: Single) of object; 

    TProgressFileStream = class(TFileStream) 
    private 
    FOnProgress: TStreamProgressEvent; 
    FProcessed: Int64; 
    FSize: Int64; 
    public 
    procedure InitProgressCounter(ASize: Int64); 
    function Read(var Buffer; Count: Integer): Integer; override; 
    function Write(const Buffer; Count: Integer): Integer; override; 
    property OnProgress: TStreamProgressEvent read FOnProgress 
     write FOnProgress; 
    end; 

    TForm1 = class(TForm) 
    ADOQuery1: TADOQuery; 
    ADOQuery1ID: TAutoIncField; 
    ADOQuery1Blob: TBlobField; 
    Button1: TButton; 
    ProgressBar: TProgressBar; 
    procedure Button1Click(Sender: TObject); 
    private 
    procedure StreamProgress(Sender: TObject; Percentage: Single); 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

{ TProgressFileStream } 

procedure TProgressFileStream.InitProgressCounter(ASize: Int64); 
begin 
    FProcessed := 0; 
    if ASize <= 0 then 
    FSize := 1 
    else 
    FSize := ASize; 
    if Assigned(FOnProgress) then 
    FOnProgress(Self, 0); 
end; 

function TProgressFileStream.Read(var Buffer; Count: Integer): Integer; 
begin 
    Result := inherited Read(Buffer, Count); 
    Inc(FProcessed, Result); 
    if Assigned(FOnProgress) then 
    FOnProgress(Self, FProcessed/FSize); 
end; 

function TProgressFileStream.Write(const Buffer; Count: Integer): Integer; 
begin 
    Result := inherited Write(Buffer, Count); 
    Inc(FProcessed, Result); 
    if Assigned(FOnProgress) then 
    FOnProgress(Self, FProcessed/FSize); 
end; 

{ TForm1 } 

procedure TForm1.Button1Click(Sender: TObject); 
var 
    Stream: TProgressFileStream; 
begin 
    ADOQuery1.Open; 
    Stream := TProgressFileStream.Create('H:\Delphi\Blobtest.docx', fmOpenRead); 
    try 
    Stream.OnProgress := StreamProgress; 
    Stream.InitProgressCounter(Stream.Size); 
    ADOQuery1.Append; 
    ADOQuery1Blob.LoadFromStream(Stream); 
    ADOQuery1.Post; 
    finally 
    Stream.Free; 
    end; 
    Stream := TProgressFileStream.Create('H:\Delphi\Blobtest2.docx', fmCreate); 
    try 
    ADOQuery1.Last; 
    Stream.OnProgress := StreamProgress; 
    Stream.InitProgressCounter(ADOQuery1Blob.BlobSize); 
    ADOQuery1Blob.SaveToStream(Stream); 
    finally 
    Stream.Free; 
    end; 
end; 

procedure TForm1.StreamProgress(Sender: TObject; Percentage: Single); 
begin 
    ProgressBar.Position := Round(Percentage * ProgressBar.Max); 
end; 

end. 

虽然这OnProgress事件的进程的文件,边实施,它代表的实际进度是整个过程包括数据库通信。

+0

谢谢@NGLN,这正是我正在寻找的,我会尝试代码尽快。 – riad

1

我认为延迟不是读取文件,而是用于数据库中的记录。我相信您可以根据文件大小进行估计,并使用“TTimer”进行项目进度,但是对于此读取,应该在一个线程中完成该文件,以便应用程序的其余部分(主线程)锁存

+0

谢谢,这是在这里提出的解决方案http://delphigroups.info/2/c3/138402.html,我正在检查出 – riad