Ir para conteúdo
Fórum Script Brasil
  • 0

Erro ao pesquisar arquivo usando * no FTP


etspaz

Pergunta

Boa tarde,

tenho um script que copia uns arquivos do FTP: mget TRAFEGO_POS_TO_12_200907*.gz

Estou passando a tarefa para o Delphi, pois com o script o usuário precisa alterar alguns parâmetros todo mês

E no Delphi eu pego esses parâmetros no banco

Usando o Indy, listei num StringList o nome dos arquivos, mas teria que usar o asterisco como uso no script:

BOA TARDE,

arqs.Add('TRAFEGO_POS_'+QR_FTP.FieldByName('UF').AsString+'_'+QR_FTP.FieldByName('CICLO').AsString+'_'+ANO_MES_CICLO+'*'+'.gz');
Para copiar:
for X := 0 to arqs.Count - 1 do
    BEGIN
      IdFTP1.get('/DIR_FTP/'+arq [x],DIR_LOCAL\'+ arqs[x],true );
    END;

Mas dá o erro:

First chance exception at $7C812A5B.

Exception class EFCreateError with message

'Cannot create file "D:\Ernesto\Automatizacao_DFAT\Documentos_atuais

\TESTE_SCR_RD\TRAFEGO_POS_AC_12_200906*.gz". A sintaxe do nome do arquivo,

pasta ou nome do volume está incorreta'. Process Project1.exe (2052)

Tem algum jeito de usar o * com este componente

Editado por Jonathan Queiroz
Não são permitidos posts em caixa alta (Jonathan);Adcionar tag's (Jonathan)
Link para o comentário
Compartilhar em outros sites

8 respostass a esta questão

Posts Recomendados

  • 0

Opa

Na verdade o problema ai nem está no componente e nem no seu programa...

e sim porque o Windows não permite que sejam criados programas que em seu nome ou caminho contenham os seguintes caracteres

fileblockedchars.jpg

então neste caso, pense em uma outra alternativa ao invés de usar os asteriscos pois assim desta forma será impossível você salvar o arquivo com estes caracteres no nome...

uma dica é trocar o asterisco por um underline por exemplo...

exemplo

uses
  StrUtils;

IdFTP1.get('/DIR_FTP/'+arq [x],AnsiReplaceStr(DIR_LOCAL\'+ arqs[x], '*', '_'),true );

ai o nome do arquivo salvo ficaria algo como

TRAFEGO_POS_AC_12_200906_.gz

abrxx

Editado por Churc
Link para o comentário
Compartilhar em outros sites

  • 0

oPA beleza cHURC,

O problema é que o * é apenas para filtrar, eu passo na hora de informar os arquivos.

Então eu não estou tendo problemas com esta regra do windows e sim em utilizar o * na pesquisa.

No script funciona, mas no Indy não, por isso acho que é com o Indy o problema.

Link para o comentário
Compartilhar em outros sites

  • 0

Já descobre que estava fazendo errado, quanto passava:

IdFTP1.get('/DIR_FTP/'+arq [x],DIR_LOCAL\'+ arqs[x],true );

Ele estava realmente tentando escrever com o *, você estava certo

Porém não sei como passar o nome com o * mesmo para listar todos que preciso, e pegar só o nome real dos arquivos listados, pra depois mandar copiar, tipo:

IdFTP1.get('/DIR_FTP/'+NMREAL,DIR_LOCAL\'+ NMREAL,true );

Link para o comentário
Compartilhar em outros sites

  • 0

Bom dia pessoal,

Problema parcialmente resolvido.

decobri como pesquisar com * no ftp:

vejam:

//pra listar os nomes de arquivos que podem estar no ftp

arqs.Add('TRAFEGO_POS_'+QR_FTP.FieldByName('UF').AsString+'_'+QR_FTP.FieldByName('CICLO').AsString+'_'+ANO_MES_CICLO+'*'+'.gz');

//depois de conectar e seguir ao diretório desejado

//pra listar os arquivos

IdFTP1.List(ListBox1.Items,arqs[x],false);

//se encontrar os arquivos

if ListBox1.Items.Count > 0 then

begin

for indice:=0 to ListBox1.Items.Count -1 do

begin

try

//inicia a transferência do arquivo

IdFTP1.Get(ListBox1.Items.Strings[indice], 'Dir_local\'+ ListBox1.Items.Strings[indice],true);

except

on e:exception do

showmessage(e.Message);

end;

...

o problema é que IdFTP1.List(ListBox1.Items,arqs[x],false) só está funcionando quando encontra e traz os arquivos corretos, mas quando não existe o arquivo dá o erro:

First chance exception at $7C812A5B. Exception class EIdReplyRFCError with message 'FECHAMENTO_CICLO_POS_AC_12_200906*.gz: No such file or directory.

'. Process Project1.exe (5208)

não entendo o q acontece, pois esta função é justamente para listar os q existem e não ter problema de tentar copiar algo q não existe, correto?

Editado por etspaz
Link para o comentário
Compartilhar em outros sites

  • 0

Amigo, se você estiver tentando baixar todos os arquivos que se encontram em uma pasta determinada no FTP é simples.

Coloque essas procedures em seu código, não se esqueça de declarar a primeira procedure lá em Type... :blush:

procedure frmDownloadFTP.DownloadFTP(Host, Username, Password, RemoteDir, LocalDir: string);

procedure DownloadDirectory(idFTP: TidFTP; Directory: string = '');
 var i: integer;
     DirListing: TStringList;
     IdFTPListItems: TIdFTPListItems;
 begin
  // update the GUI
  Application.ProcessMessages();

  // avoid trying to move to and copy current or parent dir
  if (Directory = '.') or (Directory = '..') then
   exit;

  if Directory <> '' then
   try
    // change to directory remotely
    idFTP.ChangeDir(Directory);

    // create and change to directory locally
    CreateDir(Directory);
    SetCurrentDir(Directory);
   
    Directory := IncludeTrailingPathDelimiter(Directory);
   except
    exit;
   end;

  DirListing := TStringList.Create();
  IdFTPListItems := TIdFTPListItems.Create();

  try
   idFTP.List(DirListing);
   IdFTPListItems.LoadList(DirListing);

   for i := 0 to IdFTPListItems.Count - 1 do
   begin
    case IdFTPListItems[i].ItemType of
     ditDirectory:
     begin
      DownloadDirectory(idFTP, IdFTPListItems[i].FileName);
     end;

     ditFile:
     begin
      idFTP.Get(IdFTPListItems[i].FileName, IdFTPListItems[i].FileName, true);
     end;
    end;
   end;

   if Directory <> '' then
   begin
    idFTP.ChangeDirUp();
    SetCurrentDir('..');
   end;
  finally
   DirListing.Free();
   IdFTPListItems.Free();
  end;
 end;

var idFTP: TIdFTP;
begin

 idFTP := TIdFTP.Create(nil);
 try
  idFTP.Host := Host;
  idFTP.Username := Username;
  idFTP.Password := Password;
  idFTP.Connect();

  idFTP.ChangeDir(RemoteDir);
  ForceDirectories(LocalDir);
  SetCurrentDir(LocalDir);
  DownloadDirectory(idFTP);

  idFTP.Quit();
 finally
  idFTP.Free();
 end;
end;
Certo, agora para baixar os arquivos, coloque esse código no botão.
idFTP1.ChangeDir(PASTAREMOTA);
DownloadFTP('ftp.meusite.com.br', 'usuarioftp', 'senhaftp', 'pastaremota', 'pastalocal');

Coloque seus dados no codigo acima.

Observação: ali no idFTP1.ChangeDir(PASTAREMOTA), esse PASTAREMOTA, vou te dar um exemplo, se o seu servidor quando logado no ftp ele entra direto na pasta WWW, e os arquivos que você quer baixar está na pasta ARQUIVOS que fica em www, simplesmente você deve apagar a linha idFTP1.ChangeDir(PASTAREMOTA), caso os arquivos estejam em www\arquivos\arquivos2, você deve colocar idFTP1.ChangeDir(arquivos), assim você deve colocar para baixar a pasta arquivos2, ele baixará todos os arquivos da pasta desejada.... hasuuhsauhas que explicação meio sinistra....

Espero ter ajudado....

Abraços... :blink:

Link para o comentário
Compartilhar em outros sites

  • 0

opa

fera ainda não entendo o porque do asterisco já que literalmente voce passa o nome do arquivo inteiro... o asterisco em computação é um wildcard que simboliza todos os arquivos de um determinado tipo ou tudo que contém entre x* ou *x, que é como voce está fazendo porém praticamente voce passa o nome do arquivo inteiro rs

isto

IdFTP1.List(ListBox1.Items, '*.gz', false);

listaria todos os arquivos do tipo .gz que está na pasta do FTP

isto

IdFTP1.List(ListBox1.Items, 'etspaz*', false);

listaria todos os arquivos que contém etspaz no nome tipo etspazbla.gz, etspazble.txt e tal

Unix permite nomes de arquivos com asterisco, mas Windows não então com certeza este script a qual voce se refere é em Unix?

arqs é referente a uma StringList?

o que voce pode tentar é

var
  sl: TStringList;
  iA, iB: Integer;
begin
  sl := TStringList.Create;

  IdFTP1.List(sl, '*.gz', false); //lista todos os arquivos .gz

  if sl.Count > 0 then //encontrou arquivos, vamos comparar com os que voce quer listar
  for iA := 0 to sl.Count - 1 do //anda um por um dos encontrados no FTP e compara com os que voce quer
  for iB := 0 to arqs.Count - 1 do
  if AnsiCompareText(sl[iA], arqs[iB]) = 0 then
  ListBox1.Items.Add(arqs[iB]);

  FreeAndNil(sl);
end;
AnsiCompareText compara os nomes sem ser em case-sensitive e verifica se é igual, neste caso não necessitaria mais do asterisco em
arqs.Add('TRAFEGO_POS_'+QR_FTP.FieldByName('UF').AsString+'_'+QR_FTP.FieldByName('CICLO').AsString+'_'+ANO_MES_CICLO+'*'+'.gz');
ficando
arqs.Add('TRAFEGO_POS_'+QR_FTP.FieldByName('UF').AsString+'_'+QR_FTP.FieldByName('CICLO').AsString+'_'+ANO_MES_CICLO+'.gz');

não daria certo também?

abrxx

Editado por Churc
Link para o comentário
Compartilhar em outros sites

  • 0

Churc,

O asterisitico é necessário, pois realmente passo quase o nome todo, porém:

arqs.Add('TRAFEGO_POS_'+QR_FTP.FieldByName('UF').AsString+'_'+QR_FTP.FieldByName('CICLO').AsString+'_'+ANO_MES_CICLO+'*'+'.gz');

depois de ano_mes_ciclo vem o dia que pode ser qualquer um do periodo, eu não sei qual virá, pode ter mais de um arquivo por ano_mes_ciclo.

em média são 12(ANO_MES) * 7(CICLO) * 27(uf) * qtd_dias_para_cada_ano_mes_ciclo.

visto que existem outros arquivos com que dieferem só no ano,ou mes, por isso informo quase todo nome, para não pegar arquivo errado, só o dia que não tenho parametro.

agora sobre os códigos seu e do Douglas, vou analisar e mais tarde posto algo.

Editado por etspaz
Link para o comentário
Compartilhar em outros sites

  • 0

Bom dia,

Quero informar que o problema não acontece mais.

O que me deixa curioso é que não alterei nada que pudesse influenciar, só mudei o parametro de detalhe do metodo list para true:

IdFTP1.List(ListBox1.Items,arqs[x],true);

isto porque preciso pegar a data de criação e com os detalhes ativados ele me traz esta informação, mas não acredito que isto tenha a ver com o problema.

Agora quando tem o arquivo ele traz e se não tem não acontece nada, aí vem outra função que verifica se todos arquivos do stringlist foram encontrados, se não, gera um txt informando os arquivos que eram pra estar disponiveis e não estão, tá funcionando como eu queria.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...