2

DelphiのLoadFromFile関数を使用してTable1BLOBFIELD.LoadFromFile('C:\ xxx.avi')を挿入し、SaveToFileコマンドを使用して取得します。この挿入/取得にはかなり時間がかかります(数分)。(砂時計の形をしたカーソルだけでなく)一種のプログレスバーを表示できたらいいのにと思います。SaveToFileを使用する場合、タイマーを使用してファイルサイズを確認できます(ただし、これはスレッドなしでは機能しないようです)。しかし、これはLoadFromFileの解決策ではありません。誰かが特定の解決策、ヒント、...を持っていますか?前もって感謝します

4

2 に答える 2

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イベントはプロセスのファイル側で実装されますが、それが表す実際の進行状況は、データベース通信を含む全体的なプロセスです。

于 2013-02-05T18:48:21.597 に答える
1

遅延はファイルの読み取りではなく、データベース内のレコードの遅延だと思います。「TTimer」を使用してファイルサイズとプロジェクトの進行状況に応じて見積もりを作成できると思いますが、この読み取りでは、アプリケーションの残りの部分 (メインスレッド) がラッチされるように、ファイルをスレッドで実行する必要があります。

于 2013-02-05T12:10:49.527 に答える