Otimizar Função criada Converter arquivo no formato dos para unix

02/09/2009

Tenho uma função que gera arquivos no formato windows e depois uso a rotina abaixo para converter.   Gostaria de pegar a função abaixo, e exportar a partir de um dataset para arquivo texto direto para o formato unix.         procedure ConvertToUnix(SourceFile, TargetFile:String);
var
  SAIDA: TFileStream;
  Buffer: array[0..1] of Char;
  Entrada: TFileStream;
  Lidos: Integer;
begin
  Entrada := TFileStream.Create(SourceFile, fmOpenRead);
  SAIDA   := TFileStream.Create(TargetFile, fmCreate);
  repeat
    Lidos := Entrada.Read(Buffer, 1);
    if Buffer[0] = ''#13'' then
      Continue;
    SAIDA.Write(Buffer, Lidos);
  until Lidos = 0;
  Entrada.Free;
  SAIDA.Free;
end;   Delphi 7     Att.. Ricardo Horoi          
Frigorifico Sa

Frigorifico Sa

Curtidas 0

Respostas

Rodrigo Mourão

Rodrigo Mourão

02/09/2009

Olá Ricardo,

Antes eu preciso saber como vc vai querer exportar o data set. Por Exemplo: Suponha que tenha o DataSet com Nome, Email, Telefone. Como vc vai querer exportar ?

NomeEmailTelefone
Nome; Email; Telefone;
Nome|Email|Telefone

Me diz como quere exportar que de dou os caminhos.

Abs!!

Atenciosamente,
Rodrigo Carreiro Mourão
Borland Instructor Certified
Coordenador da Consultoria em Delphi

GOSTEI 0
Frigorifico Sa

Frigorifico Sa

02/09/2009

Rodrigo,   Obrigado mais uma vez pela grande ajuda.     Utilizo a função abaixo:     procedure ExpTXT(DataSet: TDataSet; DataSetAux: TClientDataSet; Arq: string; Cabecalho: boolean; Separador, FimLinha: string; var msg: string);
var
  i,x,y, Registro : integer;
  sl: TStringList;
  st, Tipo: string;
  Mascara: array[0..100] of string;
begin
  DataSet.First;
  sl := TStringList.Create;
  Registro := 0;
  I := 0;
  try
    st := '';
    for x := 0 to DataSet.Fields.Count - 1 do
      st := st + DataSet.Fields[x].DisplayLabel + ';';
    if Cabecalho then
      sl.Add(st);
    DataSet.First;     for y := 0 to DataSetAux.RecordCount - 1 do
      begin
        Mascara[y] := Trim(DataSetAux.FieldByName('MASCARA').AsSTring);
        DataSetAux.Next;
      end;     Separador := Separadores(Separador);
    FimLinha := Separadores(FimLinha);     while not DataSet.Eof do
      begin
        Inc(Registro);         st := '';
        for i := 0 to DataSet.Fields.Count - 1 do
          begin             Tipo := Mascara[i];             if i = DataSet.Fields.Count - 1 then
              if Trim(FimLinha) = '' then
                st := st + FormatString(Trim(DataSet.Fields[i].DisplayText), Tipo)
              else
                st := st + FormatString(Trim(DataSet.Fields[i].DisplayText), Tipo) + FimLinha
            else
              st := st + FormatString(Trim(DataSet.Fields[i].DisplayText), Tipo) + Separador;           end;
        sl.Add(st);
        DataSet.Next;
      end;     sl.SaveToFile(Arq);
  finally
    begin
      //  Showmessage(DataSet.Fields[i].DisplayText);
      //  Showmessage(Inttostr(i));
      if not DataSet.eof then
        msg := 'Registro :' + InttoStr(Registro) + ' Coluna :' + Inttostr(i) + ' Conteudo :' + DataSet.Fields[i].DisplayText + #10#13 + ' Linha ' + st;
      sl.SaveToFile(Arq);
      sl.free;     end;
  end;
end;
Att.. Ricardo    
GOSTEI 0
Rodrigo Mourão

Rodrigo Mourão

02/09/2009

Olá Ricardo,

Tenta Isso. As Alterações estão em vermelho.


procedure ExpTXT(DataSet: TDataSet; DataSetAux: TClientDataSet; Arq, ArqUnix: string; Cabecalho: boolean; Separador, FimLinha: string; var msg: string);
var
  i,x,y, Registro : integer;
  sl: TStringList;
  st, Tipo: string;
  Mascara: array[0..100] of string;
begin
  DataSet.First;
  sl := TStringList.Create;
  Registro := 0;
  I := 0;
  try
    st := '';
    for x := 0 to DataSet.Fields.Count - 1 do
      st := st + DataSet.Fields[x].DisplayLabel + ';';
    if Cabecalho then
      sl.Add(st);
    DataSet.First;     for y := 0 to DataSetAux.RecordCount - 1 do
      begin
        Mascara[y] := Trim(DataSetAux.FieldByName('MASCARA').AsSTring);
        DataSetAux.Next;
      end;     Separador := Separadores(Separador);
    FimLinha := Separadores(FimLinha);     while not DataSet.Eof do
      begin
        Inc(Registro);         st := '';
        for i := 0 to DataSet.Fields.Count - 1 do
          begin             Tipo := Mascara[i];             if i = DataSet.Fields.Count - 1 then
              if Trim(FimLinha) = '' then
                st := st + FormatString(Trim(DataSet.Fields[i].DisplayText), Tipo)
              else
                st := st + FormatString(Trim(DataSet.Fields[i].DisplayText), Tipo) + FimLinha
            else
              st := st + FormatString(Trim(DataSet.Fields[i].DisplayText), Tipo) + Separador;           end;
        sl.Add(st);
        DataSet.Next;
      end;     sl.SaveToFile(Arq);
  finally
    begin
      //  Showmessage(DataSet.Fields[i].DisplayText);
      //  Showmessage(Inttostr(i));
      if not DataSet.eof then
        msg := 'Registro :' + InttoStr(Registro) + ' Coluna :' + Inttostr(i) + ' Conteudo :' + DataSet.Fields[i].DisplayText + #10#13 + ' Linha ' + st;
      sl.SaveToFile(Arq);
      ConvertToUnix(Arq, ArqUnix:String);
      sl.free;     end;
  end;
end;
Na verdade o que eu fiz foi apenas pedir mais um parametro, o caminho do arquivo unix. Depois disso apenas chamei o metodo que ja funciona.

Espero ter ajudado !!!

Abs!!

GOSTEI 0
Frigorifico Sa

Frigorifico Sa

02/09/2009

Rodrigo,   O problema é o seguinte.   Para gerar 1 arquivo na primeira função gasta em media 1 segundo.   Já para converter gasta em média 16 segundos.   Como eu tenho que gerar mais de 40 arquivos uns menores e outros maiores, a aplicação esta demorando em média 9 minutos para gerar todos os arquivos.   O que eu gostaria era reduzir este tempo.   Seria possivel incorporar a procedure dentro da função, sem ter que ficar gravando o arquivo e lendo ele para converter  gravar novamente?     Outro problema é que a aplicação fica travando a procedure geral fica dentro de uma thread encapsulada, mas parece que para algumas funçoes dentro da procedure isso não funciona.     procedure TFormIntegrador.BackgroundWorker1DoWork(Sender: TObject);
var
  Colunas, Filtro, Registros: Integer;
  msg: string;
  Historico: TStringList;
  edArquivo: TMemo;
  TInicio, TFim, TimeIni: TTime;
  Configs : TIniFile;
begin
  {
  case TTimer(Sender).Tag of
    1: Times := '1';
    2: Times := '2';
    3: Times := '3';
  end;
  }
  try
    try       if Processando <> 'sim' then
        begin
          Registros := 0;           Historico := TStringList.create();
          if FileExists('Historico' + DataParaString(date) + '.txt') then
            Historico.LoadFromFile('Historico' + DataParaString(date) + '.txt');
          Memo1.Text := Historico.Text;           if TTimer(Sender).Tag = 0 then
            Filtro := 1
          else
            Filtro := TTimer(Sender).Tag;           TInicio := time;
          Memo1.Lines.Insert(0, 'Inicio :' + IntToStr(TTimer(Sender).Tag) + ' ' + TimetoStr(time));
          Memo1.Lines.Insert(0, ' ');
          Processando := 'sim';
          AbreConexao;           sqlLayout.Close;
          sqlLayout.ParamByName('pTime').Value := Filtro;
          sqlLayout.Open;           while not sqlLayout.Eof do
            begin
              Registros := Registros + 1;
              SqlLayOut.next;             end;           pb1.Max := Registros;           sqlLayout.First;           while not sqlLayout.Eof do
          begin
              Memo1.Lines.Insert(0, sqlLayoutDESCRICAO.asstring);
              TimeIni := time;
              with ASqlSql do
                begin
                  Close;
                  SQL.Clear;
                  Sql.Add(' select comando from tbsql where codigo = :Pcodigo');
                  Parameters.ParamByName('pCodigo').Value := sqlLayoutCODIGO.AsInteger;
                  Open;
                end;
              pb1.StepBy(1);
              Application.ProcessMessages;               CDSLayouts.Close;
              sqlLayouts.Close;
              sqlLayouts.ParamByName('COD_LAY_OUT').Value := sqlLayoutCODIGO.AsInteger;
              CDSLayouts.Open;
              sqlLayouts.open;
              with sqlDados do
                begin
                  Close;
                  SQL.Clear;
                  SQL.Add( AsqlSql.fieldbyName('COMANDO').ASSTRING);
                  Open;
                end;
//                sqlDados.RecordCount;
               // sqlDados.First;
              //sqlDados.SQL.SaveToFile(sqlLayoutDESCRICAO.AsString);               if not sqlDados.IsEmpty then
                begin                   for Colunas := 0 to sqlLayouts.FieldCount - 1 do
                    begin
                      sqlLayouts.fields[COLUNAS].displaylabel := sqlLayouts.fields[COLUNAS].name;
                    end;
                  if sqlLayouts.FieldCount = 0 then
                    Memo1.Lines.Insert(0, ' Sem colunas. ');                   try
                    Msg := '';                     if chkDosUnix2.Checked then
                      ExpTXT(sqlDados, CDSLayouts, Trim('C:\uddu\') + Trim(sqlLayoutDESCRICAO.AsString), false, sqlLayoutSEPARADOR.asString, '', msg);
                      Memo1.Lines.Insert(0, 'Fim Exp :' + IntToStr(TTimer(Sender).Tag) + ' ' + TimetoStr(time));
                    if chkdosunix.Checked then
                      begin
                        ExpTXT(sqlDados, CDSLayouts, 'c:\' + Trim(sqlLayoutDESCRICAO.AsString), false, sqlLayoutSEPARADOR.asString, '', msg);
                        if Trim(sqlLayoutDATATIME.AsString) <> 'S' then
                          ConvertToUnix('c:\' + Trim(sqlLayoutDESCRICAO.AsString), Trim(sqlLayoutCAMINHO.AsString) + Trim(sqlLayoutDESCRICAO.AsString))
                        else
                          ConvertToUnix('c:\' + Trim(sqlLayoutDESCRICAO.AsString), Trim(sqlLayoutCAMINHO.AsString) + DataParaString(date, false) + HoraParaString(now) + Trim(sqlLayoutDESCRICAO.AsString));
                      end
                    else
                      ExpTXT(sqlDados, CDSLayouts, Trim(sqlLayoutCAMINHO.AsString) + Trim(sqlLayoutDESCRICAO.AsString), false, sqlLayoutSEPARADOR.asString, '', msg);
                      Memo1.Lines.Insert(0, 'Fim Converte :' + IntToStr(TTimer(Sender).Tag) + ' ' + TimetoStr(time));
                    {
                    F := TStringList.Create;
                    F.LoadFromFile(Trim(sqlLayoutCAMINHO.AsString) + 'Win'+ Trim(sqlLayoutDESCRICAO.AsString));
                    SalvaUTF8(Trim(sqlLayoutCAMINHO.AsString) + Trim(sqlLayoutDESCRICAO.AsString),F);
                    FreeAndNil(F);
                     }                   except
                    on E: Exception do
                      begin
                        Memo1.Lines.Insert(0, msg + E.Message);
                      end;
                  end;
                end
              else
              Memo1.Lines.Insert(0, 'xxxxxxxxxxxxxxxxxxxxxxxxx  Sem Registros xxxxxxxxxxxxxxxxxxxxxxx:' + IntToStr(0));
              {Try
              Memo1.Lines.Insert(0, 'Registros :' + IntToStr(sqlDados.RecordCount));
              except
              Memo1.Lines.Insert(0, 'Registros erro não foi possivel informar.');
              end;}
              Application.ProcessMessages;               sqlLayout.Next;               Memo1.Lines.Insert(0, 'Fim Arquivo Time: ' + IntToStr(TTimer(Sender).Tag) + ' ' + TimetoStr(time) + ' Duração :' + TimeToStr(time - TimeIni));
              Memo1.Lines.Insert(0, ' ');              Configs := TIniFile.Create(ExtractFilePath(Application.ExeName) + '.\Configuracoes.ini');
             chkManutencao.Checked := StrToBool(configs.ReadString('PARAMETROS','CONFIGURANDO',''));
             Configs.free;               if chkManutencao.Checked then
              begin
                Exit;
                Processando := 'nao';
              end;             end;           sqlLayout.close;
          DM.con1.Close;
          if chkDosUnix2.Checked then
            ShellExecute(handle, 'open', PChar('C:\uddu\Converterdos2unix.bat'), '', '', sw_ShowMaximized);
          //      WinExec(PChar('C:\uddu\Converterdos2unix.bat'),SW_SHOW);
          Processando := 'nao';
          TFim := time;
          Memo1.Lines.Insert(0, 'Fim Time.................................... :' + IntToStr(TTimer(Sender).Tag) + ' ' + TimetoStr(time) + ' Tempo : ' + TimeToSTr(Tfim - Tinicio));
          StatusBar1.Panels[0].Text := 'Fim Time.................................... :' + IntToStr(TTimer(Sender).Tag) + ' ' + TimetoStr(time) + ' Tempo : ' + TimeToSTr(Tfim - Tinicio);
          Memo1.Lines.Insert(0, ' ');
          pb1.Max := 0;           Historico.Text := Memo1.Text;
          Historico.SaveToFile('Historico' + DataParaString(date) + '.txt');
          Historico.Free;
          //Memo1.Text := '';         end
      else
        begin           Memo1.Lines.Insert(0, 'Tentativa: Arquivos em processamento Time : ' + InttoStr(TTimer(Sender).Tag) + ' Hora : ' + TimetoStr(time));
          Memo1.Lines.Insert(0, ' ');
        end;     except
      on E: Exception do
        begin           Memo1.Lines.Insert(0, 'Erro no Processamento ' + ' Hora : ' + TimetoStr(time) + E.Message);
          Processando := 'nao';
          Historico.Free;         end;
    end;
  except
    begin

          end;
  end; end;  
GOSTEI 0
Rodrigo Mourão

Rodrigo Mourão

02/09/2009

Olá Ricardo,

Bem a demora se deve ao fato que a rotina de conversao para unix le o arquivo byte a byte. Com isso o tempo se extende. Fazer tudo de uma vez como vc falou, para gerar o arquivo ja no formato eu acho que nao é possivel. Digo eu acho levando em conta o conhecimento que eu tenho. Isso porque você esta usando a classe TStringList e para cada nova linha do arquivo utiliza o metodo add(). Com isso, devido ao comportamento da classe TStringList, a quebra de linha padrao windows #10#13 e adicionada no arquivo.

Para que a coisa pudesse ser feita tudo junto a classe TStringList deveria ter um metodo SaveToFileUnix por exemplo que ja salvasse com o formato unix.

No delphi 2009 podemos chamar o SaveToFile(nomedoarquivo, Encoding). Eu não pesquisei a fundo mas acredito que la possa ter um encoding para unix pois suporte ate unicode.

Agora quanto ao usa da Thread eu teria que ver como a coisa esta sendo feita para emitir um parecer mais detalhado.

Abs!


GOSTEI 0
Frigorifico Sa

Frigorifico Sa

02/09/2009

Rodrigo,   Vou tentar converter sem usar a rede e depois copiar para a rede, isso tb pode estar influenciando um pouco.   Pode encerar.   Obrigado pela atenção.   Abcs.   Att.. Ricardo
GOSTEI 0
Rodrigo Mourão

Rodrigo Mourão

02/09/2009

Vlw meu camarada !!

Abs!
GOSTEI 0
POSTAR