O Delphi vem incluindo há bastante tempo em sua paleta de componentes o tratamento para um amplo conjunto de protocolos. Esses componentes são o produto de um projeto Open Source chamado Indy Internet Direct e estão disponíveis para várias plataformas de desenvolvimento - Delphi, C++, C#, etc. Eles encapsulam os detalhes de mais baixo nível do funcionamento de cada protocolo, simplificando bastante a sua utilização. Há componentes para considerar ambos os lados de uma comunicação, permitindo a criação tanto de aplicações servidoras em relação a um protocolo quanto aquelas que serão apenas Clients, isto é, consumidoras do serviço provido por um servidor.
No caso do FTP, vou me ater ao componente TIdFTP, que implementa o lado Client de uma comunicação para transferência de arquivos. O componente tem métodos para tratar os comandos inerentes a um Client FTP; portanto, a mesma instância pode tratar tanto o envio quanto o recebimento de arquivos, dentre outras possibilidades.
Qualquer que seja a operação desejada, o primeiro passo tem que ser a conexão com um servidor. O exemplo abaixo preenche as propriedades mais importantes do FTP:
IdFTP1.Disconnect();
IdFTP1.Host := 'ftp.abc71.com.br';
IdFTP1.Port := 21;
IdFTP1.Username := 'usuario_para_login';
IdFTP1.Password := 'senha';
IdFTP1.Passive := false; { usa modo ativo }
IdFTP1.RecvBufferSize := 8192;
try
{ Espera até 10 segundos pela conexão }
IdFTP1.Connect(true, 10000);
except
on E: Exception do
_Erro = E.Message;
end;
Os parâmetros Host e Port identificam o endereço do servidor FTP com o qual queremos conectar. O Username e a Password servem para fazer o login naquele servidor; são informações que você deve conhecer previamente - aqui, os dados fornecidos são apenas exemplos. Alguns servidores permitem que se conecte anonimamente; para isso é recomendado que se informe um endereço de email em Password. Caso você esteja tentando fazer a conexão a partir de um computador que só se conecta na rede através de um proxy, use a propriedade ProxySettings para complementar as configurações.IdFTP1.Host := 'ftp.abc71.com.br';
IdFTP1.Port := 21;
IdFTP1.Username := 'usuario_para_login';
IdFTP1.Password := 'senha';
IdFTP1.Passive := false; { usa modo ativo }
IdFTP1.RecvBufferSize := 8192;
try
{ Espera até 10 segundos pela conexão }
IdFTP1.Connect(true, 10000);
except
on E: Exception do
_Erro = E.Message;
end;
O valor de RecvBufferSize indica o tamanho do buffer interno para a recepção de dados; normalmente, ele não precisa ser alterado. Finalmente, a função Connect faz todo o trabalho para estabelecer a conexão, aguardando um tempo máximo especificado na própria função. O primeiro parâmetro passado a ela indica se o login deve ocorrer junto com a conexão. Se optar por não fazer o login neste momento, você terá que chamar manualmente a função Login.
Com a conexão estabelecida e o login feito com sucesso, enviar um arquivo (fazer o upload) é bastante simples. Basta chamar a função Put do TIdFTP:
IdFTP1.Put (AFileName, ADstFileName, false);
O primeiro parâmetro é o nome completo do arquivo que você quer mandar, incluindo o caminho. O segundo parâmetro é como o arquivo será nomeado no servidor, isto é, o seu arquivo pode ser enviado com um nome diferente. Para mantê-lo com o mesmo nome no servidor, simplesmente passe um texto vazio no lugar. Para mandar para uma pasta específica no servidor, informe o nome dela como parte do nome do arquivo. O componente FTP também possui métodos para navegar pela árvore de pastas, criar uma nova pasta e listar as pastas atualmente existentes, caso seja necessário. O último parâmetro passado ao Put sinaliza ao servidor o que fazer caso um arquivo com o mesmo nome já exista. Informar true fará com que o servidor inclua o conteúdo do seu arquivo no final do arquivo já existente.Fazer o download de um arquivo também é simples. Basicamente, chame a função Get do TIdFTP:
IdFTP1.Get (AFileName, ADstFileName, true, false);
Aqui a situação é invertida em relação ao Put. O nome de arquivo passado no primeiro parâmetro identifica um arquivo no servidor, enquanto o segundo parâmetro é o nome com o qual queremos salvá-lo localmente. O terceiro parâmetro determina se o download sobreporá ou não um arquivo local que tenha o mesmo nome. Por fim, o último parâmetro indica se o download deve tentar prosseguir a partir do ponto onde uma tentativa anterior tenha sido interrompida.Quando terminar o uso do componente, é conveniente chamar o método Quit para encerrar a conexão e devolver os recursos usados pelo sistema operacional.
As operações Get e Put podem ser bastante demoradas, dependendo do tamanho do arquivo sendo transferido. Então, para evitar que a aplicação pareça travada, é possível responder a alguns eventos no TIdFTP para dar ao usuário um retorno sobre o andamento da operação. O evento OnStatus notifica o programa a respeito de mudanças no estado da conexão. Já os eventos OnWorkBegin, OnWork e OnWorkEnd tratam do progresso da transferência do arquivo, informando o tamanho esperado do trabalho, a evolução da quantidade de bytes transferida enquanto a operação está em andamento e, por fim, sinalizando a conclusão da transferência. Com isso, podemos, por exemplo, incluir uma barra de progresso na tela para acompanhar toda a operação.

Meu amigo Parabéns muito bem explicado gostei .
ResponderExcluirContinue assim , o pessoal fala que acha de tudo na internet no Google sim é correto se acha de tudo mas nao com uma boa explicação .
E com bom conteudo.
Voce esta de parabéns.
Somos vizinhos de cidade nao sei se vc é de Bauru.
Muito bom artigo. Me ajudou muito.
ResponderExcluirBom dia, cara adorei esse exemplo com ele consegui desenvolver minha aplicação sem problemas só que quando faço a funçao put nem sempre da certo por exemplo to enviando um arquivo de texto e um arquivo com extensao .v35 que é de uma aplicacao nossa dae ele da um erro "file successfuly uploaded" e nao envia nada da essa mensagem e ja para tudo isso quando começa a enviar arquivo e tem outros computadores que ele vai até quase o fim e da '0,5 não é valor inteiro valido' ja testei enviar outros arquivos como documento do word, etc.. e da o mesmo erro sera que pode me ajudar nao encontrei nada sobre isso
ResponderExcluirJamil
ExcluirPela descrição que você faz, tenho a impressão que o problema está no tratamento do progresso da transferência do arquivo. Revise o código que você está usando nos eventos OnWorkBegin, OnWork e OnWorkEnd. Depure-os ou vá comentando trechos desses códigos pra tentar descobrir o que há de errado.
Att.
parabens, muito bom seu post.
ResponderExcluirmuito bom seu post. me ajudou muito.
ResponderExcluirMuito bom consegui fácil, só gostaria de saber como baixar mais de um arquivo, na mesma function
ResponderExcluirAdriano
Adriano
ExcluirNão sei se entendi bem sua dúvida; pra baixar mais arquivos, é só chamar o Get para cada um deles. Se o problema está no acompanhamento do download, vc pode, por exemplo, mostrar janelas diferentes com a evolução de cada um ou colocar uma barra de progresso extra para indicar a qtde de arquivos sendo baixados.
[]s
Obrigado pela dica, funcionou 100% aqui.
ResponderExcluirO único problema que estava dando para mim era o erro "Illegal PORT command".
Para resolver, só precisei mudar para modo "passivo", alterando a linha:
IdFTP1.Passive := true; { usa modo passivo }
Abraços!
Fabio
Bom dia,
ResponderExcluirExiste alguma forma de fazer o upload continuar de onde parou por ultimo, por ex. caso a maquina reinicie ou caia a conexao com a internet, o sistema continuar em vez de reiniciar o processo do zero?
Grato
Rodrigo
Rodrigo
ExcluirVi na versão 10.5 do Indy do Delphy XE2 que há uma sobrecarga da função Put que permite informar se o conteúdo do "stream" sendo enviado deve ser anexado ao arquivo existente no Servidor.
Obviamente, isso só funcionará se o servidor FTP em questão der suporte ao "resume" de upload.
[]s
Oi Luis,
ResponderExcluirA linha _Erro = E.Message; está dando erro. Substituir por ShowMessage...
O problema é que não tô conseguindo a conexao e não tenho
mensagem de erro específica.
O que faço ?
Há alguns componentes de log do Indy que vc pode incluir em sua aplicação para ajudar a depurá-la. Eles são conhecidos como "interceptadores" (intercepts). Veja, por exemplo, o TIdLogFile, onde toda a comunicação com o servidor pode ser interceptada e gravada num arquivo.
Excluir[]s
Luis, Bom dia,
ResponderExcluirEstou utilizando o IDFTP para upload de arquivos. Quando o arquivo chega no FTP o tamanho do mesmo aumenta consideravelmente, de 500 kb para mais de 1 mb. Você imagina o que possa estar acontecendo?
Obrigada!
Verifique se não existe um arquivo com o mesmo nome no servidor. Nessa situação, a função put acrescentará o novo conteúdo no final do arquivo existente - se você passou TRUE no último parâmetro.
Excluir[]s
Muito obrigada! Até mais!
ExcluirLuís:
ResponderExcluirCriei uma aplicação dessa forma e não está realizando o download.
Ao debugar constatei que a conexão é estabelecida normalmente, mas na hora de do download com o FTP1.Get não anda, simplesmente para, tentei monitorar pelo evento OnStatus e a última mensagem que ele exibe é: Starting FTP Transfer. Mas ai ele fica parado e não baixa o arquivo.
Em apenas uma das vezes apresentou o erro: SocketError # 10053 Só que não consegui identificar o que é.
Caso possa auxiliar fico agradecido.
O erro 10053 está associado ao encerramento prematuro da conexão, forçado por algum outro software. Veja, por exemplo, se não há um firewall barrando a comunicação ou se há um proxy que sua aplicação tenha que levar em conta.
ExcluirDependendo do cenário, você pode obter um erro mais preciso adicionando log do próprio Indy ao seu programa. Veja, por exemplo, o TIdLogFile.
[]s