quarta-feira, 16 de agosto de 2017

Copiando Um Arquivo Com Um Gauge

Muitas vezes, quando temos a necessidade de copiar um arquivo de um lugar para outro, é interessante mostrar ao usuário o andamento da cópia.
Para tal, coloque em sua aplicação um gauge (optei por um gauge, mas poderia muito bem ser uma progressbar) e um botão para iniciar a cópia. No código onClick do botão, coloque este código. Neste exemplo, o programa cria um diretório de back-up cujo nome do mesmo é a data da cópia no formato AAAAMMDD. No nosso exemplo, chamei o gauge de ga_copia.

procedure Tfrm_Manut.bt_backupClick(Sender: TObject);
var
  strArqOrigem, // Nome do arquivo de origem da cópia
  strArqDestino: string; // Nome do arquivo de destino da cópia
  wDia,wMes,wAno: Word;
begin
  try
    // Aciona o indicativo de progresso da cópia
    ga_copia.Visible := True;
    ga_copia.Progress := 0;
    // Monta os nomes de arquivo - Primeiro recupera de um AdoConnection
    // o nome do arquivo a ser copiado
    strArqOrigem := dm_spark.ADO_Spark.Properties[7].Value;
    // Agora vai montar o nome do arquivo de destino.
    DecodeDate(Date, wAno, wMes, wDia);
    strArqDestino := 'C:\prodata\copia\' + FormatFloat('0000', WAno);
    strArqDestino := strArqDestino + FormatFloat('00', wMes);
    strArqDestino := strArqDestino + FormatFloat('00', wDia);
    strArqDestino := strArqDestino + '\' + ExtractFileName(strArqOrigem);
    // Desconecta o banco de dados
    dm_spark.ADO_Spark.Close;
    Repaint;
    // Inicia a cópia
    CopyFile(strArqOrigem, strArqDestino);
  finally
    // Reconecta o banco de dados
    dm_spark.ADO_Spark.Open;
    ga_copia.Visible := False;
  end;
end;



Agora que já definimos como e quando a cópia será disparada, vamos definir a procedure copyfile que é o motor da nossa cópia de arquivo. Esta procedure é que vai fazer a cópia e incrementar o Gauge.

procedure Tfrm_Manut.CopyFile(Source, Destination: string);
var
  FromF,ToF: file of byte;
  Buffer: array[0..4096] of char;
  NumRead: Integer;
  FileLength: LongInt;
  NewPath: string;
begin
  // Antes de copiar, verifica se já existe o diretório
  // Caso o diretório não exista, o mesmo vai ser criado
  NewPath := ExtractFilePath(Destination);
  if not DirectoryExists(NewPath) then
  begin
    CreateDir(NewPath);
  end
  else
  begin
    if FileExists(Destination) then
    begin
      if Application.MessageBox('O arquivo-destino da cópia de segurança já existe ' + #13#10 +
        'Deseja sobrepôr o mesmo com a nova cópia ?', 'Segurança',
        MB_YESNO + MB_ICONQUESTION) = MRNO then
        Exit;
    end;
  end;
  // Copia o arquivo
  // Abre o arquivo de origem e cria o arquivo destino
  AssignFile(FromF, Source);
  Reset(FromF);
  AssignFile(ToF, Destination);
  ReWrite(ToF);
  FileLength := FileSize(FromF);
  with ga_copia do
  begin
    MinValue := 0;
    MaxValue := FileLength;
    while FileLength > 0 do
    begin
      BlockRead(FromF, Buffer[0], SizeOf(Buffer), NumRead);
      FileLength := FileLength - NumRead;
      BlockWrite(ToF, Buffer[0], NumRead);
      AddProgress(NumRead);
    end;
    CloseFile(FromF);
    CloseFile(ToF);
  end;
end;

Nenhum comentário:

Postar um comentário