sexta-feira, 15 de junho de 2012

FTP em Java





Fala galera! Esta próxima dica é bastante útil para quem pretende se conectar a servidores ftp, assim como enviar e efetuar downloads de arquivos! Vamos lá


Primeiramente vamos entender oque é o Ftp e qual sua particularidade.
File Transfer Protocol (FTP) é um padrão de protocolo de rede usado para transferir arquivos de um hospedeiro para outro host em um TCP baseado em rede, como a Internet . Ele é frequentemente usado para carregar páginas da Web e outros documentos de uma máquina de desenvolvimento privada para um servidor público. FTP é construído sobre um cliente-servidor e usa arquitetura de controle separado e conexões de dados entre o cliente eo servidor. usuários FTP podem se autenticar usando um texto sinal em protocolo, normalmente na forma de um nome de usuário e senha , mas pode ligar anonimamente, se o servidor está configurado para permitir isso. Para a transmissão segura que se esconde (criptografada) o nome de usuário e senha, e criptografado sobre o conteúdo.

As primeiras aplicações de cliente FTP eram interativas de linha de comando, ferramentas, implementação de comandos padrão e sintaxe. interfaces gráficas já foram desenvolvidas para muitos dos sistemas operacionais de desktops populares em uso hoje, incluindo programas gerais web design, como Microsoft Expression Web , e especialista em clientes FTP, como CuteFTP .

Diferenças de HTTP
FTP opera na camada de aplicação do modelo OSI , e é usado para transferir arquivos usando TCP / IP . Para isso, um servidor FTP tem que estar rodando e esperando para receber os pedidos. O cliente é, então, um computador capaz de se comunicar com o servidor na porta 21. Esta ligação, a chamada conexão de controle, permanece aberta para a duração da sessão. Uma segunda ligação, chamado a ligação de dados, pode ser aberta pelo servidor da porta 20 para uma porta de cliente negociado (modo activo), ou pelo cliente a partir de uma porta arbitrária para uma porta de servidor negociado ( modo passivo), como exigido para transferir dados de arquivos. A conexão de controle é usado para a administração da sessão, por exemplo, comandos de identificação e senhas trocadas entre o cliente eo servidor usando um protocolo telnet. Para exemplo "filename RETR" seria transferir o arquivo especificado a partir do servidor para o cliente. Devido a esta estrutura de duas portas, FTP é considerado um protocolo para fora-de-banda, em oposição a um protocolo de dentro da banda, tais como HTTP .

Comunicação e transferência de dados


O servidor responde pela conexão de controle com códigos de três dígitos de status em ASCII com uma mensagem de texto opcional. Por exemplo, "200" (ou "200 OK") significa que o último comando foi bem-sucedida. Os números representam o código para a resposta e o texto opcional representa uma explicação legível ou pedido (conta <Need por exemplo, para armazenar file>). Uma transferência contínua de dados de arquivos através da conexão de dados pode ser cancelada usando uma interrupção enviada através da conexão de controle.
Ilustração de iniciar uma conexão passiva usando a porta 21
FTP pode ser executado no modo ativo ou passivo, que determina como a conexão de dados é estabelecida.  No modo ativo, o cliente cria uma conexão de controle TCP para o servidor e envia o endereço IP do servidor do cliente e um número de porta arbitrária cliente, e espera até que o servidor inicia a conexão de dados sobre TCP para o endereço IP do cliente e o número da porta do cliente. Em situações onde o cliente está atrás de um firewall e incapaz de aceitar conexões TCP, o modo passivo pode ser usado. Neste modo, o cliente usa a conexão de controle para enviar um comando PASV para o servidor e, em seguida, recebe um endereço IP do servidor eo número da porta do servidor a partir do servidor, que o cliente usa para abrir uma conexão de dados uma porta cliente arbitrário para o endereço IP do servidor eo número da porta do servidor recebido. Ambos os modos foram atualizados em setembro de 1998 para apoiar IPv6 . Outras mudanças foram introduzidas para o modo passivo, nesse momento, atualizando-a para o modo passivo prolongado.

Um recurso que já existe há um bom tempo, mas que é pouco discutido para aplicação prática, é o desenvolvimento de clientes de FTP utilizando o pacote Net da Jakarta Commons. A grande vantagem de criar seu próprio cliente FTP é manipular e mesclar sua aplicação Java sem a ajuda de um programa externo. Com isso é possível associar à sua aplicação uma rotina de backup para uma área no servidor FTP ou um Web Service que fornece informações de um servidor FTP remoto, por exemplo.
Antes de mais nada, devemos fazer o download da biblioteca Commons/Net localizada no site. Após efetuado o download será necessário adicionar ao CLASSPATH o arquivo commons-net-1.4.1.jar (versão mais atual até a publicação deste artigo).



 Abaixo segue um exemplo de conexão no servidor FTP, listando os arquivos em uma determinada pasta:
 package br.com.java;
 import java.io.IOException;
import java.net.SocketException;
 import org.apache.commons.net.ftp.FTPClient;
 public class FTPConnect {
      public static void main (String[] args) throws SocketException,
                                                     IOException {
                 FTPClient ftp = new FTPClient();
            ftp.connect( "ftp.petrobras.com.br" );
            ftp.login( "usuario""senha" );
            ftp.changeWorkingDirectory ("meuDir");
            String[] arq = ftp.listNames();
            System.out.println ("Listando arquivos: \n");
            for (String f : arq){
                  System.out.println(f);            
            }
      }
}

Exemplo de saida:

RD-4410-00073A[191546].log
RD-4410-00074A[191602].log
MeuArquivo.doc
SeuArquivo.java
NossoArquivo.txt


Na primeira linha é instanciada a classe FTPClient, utilizada para conectar ao servidor FTP. Segue a descrição dos métodos:
·         connect(String Servidor) – Conecta ao Servidor FTP
·         login (String usuario, String senha) – efetua o login no Servidor
·         changeWorkingDirectory (String caminho) – Muda o diretório de trabalho do servidor
·         listFiles() - Retorna uma lista de Objetos do tipo FTPFile
·         listNames() - Retorna um array de Strings contendo o nome dos arquivos no diretório de trabalho atual
·         listNames(String caminho) – Mesmo que o anterior, mas passando como parâmetro o caminho do diretório a ser listado.
FTPFile é uma classe que fornece as informações dos arquivos armazenados no FTP. Isso nós dá a possibilidade de obter dados relacionados aos arquivos armazenados no servidor.
Descrição de alguns métodos da classe FTPFile:
·         getName() - Retorna o nome do arquivo
·         getSize() - Retorna o tamanho do arquivo em bytes
·         isDirectory() - Retorna true se o FTPFile é um diretório
·         isFile() - Retorna true se o FTPFile é um arquivo
·         isSymbolicLink () - Retorna true se o FTPFile é um link simbólico
·         getType() - Retorna um int que define o tipo do FTPFile (0 para Arquivo, 1 para Diretório e 2 para Link Simbólico)
Enviando Arquivos 
O armazenamento de arquivos é feito de forma bem simples, conforme exemplo abaixo:

package br.com.java;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.SocketException;

import org.apache.commons.net.ftp.FTPClient;

public class FTPConnect {
      public static void main (String[] args) throws SocketException,
                                                     IOException {
     
            FTPClient ftp = new FTPClient();
            ftp.connect( "ftp.meudominio.com.br" );
            ftp.login( "usuario""senha" );
            FileInputStream arqEnviar =
                  new FileInputStream("/Users/glaucio/Documents/artigoFTP.doc");
            if (ftp.storeFile ("meuarquivo.doc", arqEnviar))
                  System.out.println("Arquivo armazenado com sucesso!");
            else
                  System.out.println ("Erro ao armazenar o arquivo.");
         
      }
}


Saída:
Arquivo armazenado com sucesso!
Para enviar um arquivo é preciso instanciar um objeto InputStream para passar como parâmetro no método storeFile da classe FTPClient. O primeiro parâmetro é o nome do arquivo que será armazenado no FTP e o segundo é o InputStream, como dito anteriormente.
Recebendo Arquivos
Abaixo segue o código-exemplo para o download de arquivos:

package br.com.java;

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.SocketException;

import org.apache.commons.net.ftp.FTPClient;

public class FTPConnect {
      public static void main (String[] args) throws SocketException,
                                                     IOException {
     
            FTPClient ftp = new FTPClient();
            ftp.connect( "ftp.meudominio.com.br" );
            ftp.login( "usuario""senha" );
            ftp.changeWorkingDirectory ("grdt_websigem");
            String[] arq = ftp.listNames();
            FileOutputStream fos =
                    new FileOutputStream( "/Users/glaucio/Desktop/meulog.log" );
            if (ftp.retrieveFile( "RD-4410-00412[192017].log", fos ))
                  System.out.println("Download efetuado com sucesso!");
            else
                  System.out.println ("Erro ao efetuar download do arquivo.");
      }

}
A única diferença que podemos observar com relação ao exemplo anterior é o tipo de Stream utilizado. Para enviar arquivos é necessário instanciar um FileInputStream e, para receber, é preciso ter um FileOutputStream. Além disso, o método retrieveFile da classe FTPClient recebe o nome do arquivo a ser baixado e também caminho em que o documento será armazenado (de acordo com o exemplo, para a minha área de trabalho). Ambos os métodos, storeFile e retrieveFile, retornam um booleano para checar se a operação foi concluída com sucesso.
Efetuar logout e desconectar
Sempre procure efetuar logout e desconectar do FTP antes de finalizar a sua aplicação para liberar os recursos do servidor. Para isto seguem os comandos da classe FTPClient:

ftp.logout();
ftp.disconnect();
Código completo:
package br.com.java;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.SocketException;

import org.apache.commons.net.ftp.FTPClient;

public class FTPConnect {
      public static void main (String[] args) throws SocketException,
                                                     IOException{
     
            FTPClient ftp = new FTPClient();
            //Fazendo a conexão
            ftp.connect( "ftp.petrobras.com.br" );
            //Efetuando o Login
            ftp.login( "iercps""iercpsadmin" );
            //Mundando o diretório de trabalho
            ftp.changeWorkingDirectory ("grdt_websigem");
            //Adiquirindo o nome dos arquivos / diretórios existentes
            String[] arq = ftp.listNames();
            System.out.println ("Listando arquivos: \n");
            for (String f : arq){
                  System.out.println(f);            
            }
            //Fazendo o download do arquivo RD-4410-00412[192017].log para
              meulog.log
            FileOutputStream fos =
                    new FileOutputStream( "/Users/glaucio/Desktop/meulog.log" );
        
            if (ftp.retrieveFile( "RD-4410-00412[192017].log", fos ))
                  System.out.println("Download efetuado com sucesso!");
            else
                  System.out.println ("Erro ao efetuar download do arquivo.");
           
            //Fazendo o upload do arquivo artigoFTP.doc para o ftp com um novo
              nome (meuarquivo.doc)
            FileInputStream arqEnviar =
                 new FileInputStream ("/Users/glaucio/Documents/artigoFTP.doc");
            if (ftp.storeFile ("meuarquivo.doc", arqEnviar))
                  System.out.println("Arquivo armazenado com sucesso!");
            else
                  System.out.println ("Erro ao armazenar o arquivo.");

            ftp.logout();
            ftp.disconnect();

      }
}     


Todas as funções citadas podem ser feitas via console ou algum programa de FTP sem problemas. Segue um exemplo abaixo:
glaucio$ ftp ftp.meudominio.com.br
Connected to ftp.meudominio.com.br.
220 s6000ws30 Microsoft FTP Service (Version 5.0).
Name (ftp.meudominio.com.br:glaucio): glaucio   
331 Password required for glaucio.
Password:
230-----------------------------------------
230-Servidor FTP MeuDominio
230-----------------------------------------
230 User glaucio logged in.
Remote system type is Windows_NT.
ftp> cd grdt_websigem
250 CWD command successful.

ftp> get RD-4410-00412[192017].log
local: RD-4410-00412[192017].log remote: RD-4410-00412[192017].log
227 Entering Passive Mode (200,179,65,44,18,8)
125 Data connection already open; Transfer starting.
100% |*************************************|   385     320.25 KB/s    00:00
226 Transfer complete.
385 bytes received in 00:00 (95.30 KB/s)
put
(local-file) /Users/glaucio/Desktop/meulog.log
(remote-file) meulog.txt
local: /Users/glaucio/Desktop/meulog.log remote: meulog.txt
227 Entering Passive Mode (200,179,65,44,18,10)
125 Data connection already open; Transfer starting.
100% |*************************************|   385       4.78 KB/s    --:-- ETA
226 Transfer complete.
385 bytes sent in 00:00 (2.43 KB/s)

Através da API Commons Net é possível manipular diversas funcionalidades oferecidas para o uso de um servidor FTP. Neste artigo foi visto como conectar, logar, enviar e receber arquivos para uma área de FTP. Agora é só criar as suas próprias rotinas para enviar e receber arquivos a partir de sua aplicação Java. Um exemplo do tipo seria verificar se algum arquivo foi modificado na máquina local e enviá-lo para uma área de FTP caso a modificação tenha sido feita. Podemos também agendar uma rotina que faça o backup de um servidor para outro, escolhendo somente arquivos PDF, por exemplo


Então é isso! Até a próxima!

Veja Também: 







Admin: Bruno

Olá Galera! muito grato por estarem acessando nosso blog. Espero que seja possível transmitir de forma compreensível um pouco de meus conhecimentos em programação, para esta comunidade de desenvolvedores que cresce cada vez mais! Espero que Gostem! Abraço! E meu enorme obrigado à Renato Simões, Átila Soares,Wanderson Quinto, Emerson e a toda galera que sempre ajudou meu sincero obrigado....
Especialmente a Natalia Failache e Rita de Cassia que sempre apoiaram este sonho....

De seu amigo Bruno Rafael.