Olá,
Alguem poderia me ajudar, porque eu estou querendo fazer um programa que o usuário final poderia digitar uma URL para um arquivo tipo: “http://www.site.com.br/java/File.zip”. Lembrando que eu sou meio que iniciante.
Obrigado,
Nathan Paulino Campos
Olá nathanpc. Vou apresentar um método pronto (bem simples) que você pode utilizar para gravar arquivos a partir de uma URL.
public static File gravaArquivoDeURL(String stringUrl, String pathLocal) {
try {
//Encapsula a URL num objeto java.net.URL
URL url = new URL(stringUrl);
//Queremos o arquivo local com o mesmo nome descrito na URL
//Lembrando que o URL.getPath() ira retornar a estrutura
//completa de diretorios e voce deve tratar esta String
//caso nao deseje preservar esta estrutura no seu disco local.
String nomeArquivoLocal = url.getPath();
//Cria streams de leitura (este metodo ja faz a conexao)...
InputStream is = url.openStream();
//... e de escrita.
FileOutputStream fos = new FileOutputStream(pathLocal+nomeArquivoLocal);
//Le e grava byte a byte. Voce pode (e deve) usar buffers para
//melhor performance (BufferedReader).
int umByte = 0;
while ((umByte = is.read()) != -1){
fos.write(umByte);
}
//Nao se esqueca de sempre fechar as streams apos seu uso!
is.close();
fos.close();
//apos criar o arquivo fisico, retorna referencia para o mesmo
return new File(pathLocal+nomeArquivoLocal);
} catch (Exception e) {
//Lembre-se de tratar bem suas excecoes, ou elas tambem lhe tratarão mal!
//Aqui so vamos mostrar o stack no stderr.
e.printStackTrace();
}
return null;
}
Espero que tenha ajudado. Isto não é exatamente java avançado, e algumas buscas no Google poderiam ter lhe ajudado bastante, pois vários sites oferecem snippets prontos com várias maneiras de executar tarefas corriqueiras como esta.
Veja a descrição das classes e métodos utilizados neste exemplo na especificação da API do Java, e você irá entender exatamente o que o programa faz. Lembre-se que a melhor maneira de aprender é experimentando!
–mcbrain
1 curtida
Olá mcbrain,
Obrigado pelo código, eu o compilo e dá tudo certo, mas quando eu vou executar o arquivo class, ele me volta esse erro:

Obrigado,
Nathan Paulino Campos
[quote=nathanpc]Olá mcbrain,
Obrigado pelo código, eu o compilo e dá tudo certo, mas quando eu vou executar o arquivo class, ele me volta esse erro:

Obrigado,
Nathan Paulino Campos[/quote]
Ah, Nathan, já deu pra ver que você é novo no Java mesmo! 
Para que um arquivo java compilado possa ser executado, ele precisa de um ponto de entrada, o método “main()”.
Coloque o seguinte método antes ou depois do método estático gravaArquivoDeURL() na classe que você está usando, recompile e execute.
public static void main(String[] args) {
gravaArquivoDeURL("http://www.google.com.br/index.html","C:\\");
}
Este exemplo irá gravar a página de índice do Google na raiz do seu PC. Pra não perder a viagem, dê uma olhada nos tutoriais da Sun sobre o Java. Uma vez que você domine os conceitos básicos, vai ficar muito mais fácil criar seus próprios programas. Abraços!
– mcbrain
Muito Obrigado mcbrain, mas sem querer ser muito pidão você poderia me dizer se da para que o usuário digitase a URL para o arquivo, só para melhorar o programa e já saber para mais tarde se eu precisar.
Mas Muito Muito Obrigado,
Nathan Paulino Campos
A forma mais simples é passar a URL como argumento do programa, e já que vamos fazer isso, também passar o path de destino da gravação.
Seu método main, portanto, deverá aceitar 2 argumentos. Veja que ele tem apenas um parâmetro: um array de Strings chamado args. Isto é fixado pela especificação da linguagem Java. A JVM irá encaspular cada argumento da chamada do programa em uma String do parâmetro args, que podem ser referenciados e manipulados dentro do programa. Para usar vários argumentos na chamada do programa, separe-os por um espaço.
Altere o seu método main para o seguinte:
public static void main(String[] args) {
gravaArquivoDeURL(args[0], args[1]);
}
Após compilado o programa, chame-o com o comando:
java FileDownload http://www.google.com/index.html c:\
[]s
–mcbrain
Muito obrigado mcbrain, muito obrigado mesmo.
Abraços!!
Desculpe minha ignorancia, estou a horas tentando fazer com o Buffered mas não esta indo de jeito nenhum!
Alguem poderia me dar uma ideia de como seria?
Obrigado.
#Edit
Se não fosse pedir muito, como eu pego o nome do arquivo que esta vindo pelo InputStream? Thanks!
[quote=Neri J?ior]Desculpe minha ignorancia, estou a horas tentando fazer com o Buffered mas não esta indo de jeito nenhum!
Alguem poderia me dar uma ideia de como seria?
Obrigado.
#Edit
Se não fosse pedir muito, como eu pego o nome do arquivo que esta vindo pelo InputStream? Thanks![/quote]
Um dos construtores do BufferedWriter recebe um Writer, e um int com o tamanho do buffer como argumentos. Se você estiver escrevendo em um arquivo, pode usar um FileWriter, que por sua vez pode receber um objeto File como argumento no construtor:
BufferedWriter bw = new BufferedWriter(new FileWriter(new File("/home/meuarquivo.txt")),2048);
Depois é só usar o método write() do BufferedWriter e sucesso.
Edit: gramática.
Olá a todos, estou precisando de uma ajuda.
Estou utilizando a seguinte classe para fazer o download de um arquivo via FTP:
TesteDownloadArquivoExcel
package testemain;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Level;
import java.util.logging.Logger;
public class TesteDownloadArqExcel {
public static void main(String[] args) {
if (downloadArquivoExcel()) {
System.out.println("Download concluído com sucesso");
} else {
System.out.println("Download não concluído");
}
}
private static boolean downloadArquivoExcel() {
InputStream is = null;
BufferedInputStream buf = null;
FileOutputStream out = null;
boolean ok = false;
try {
URL url = new URL("ftp://User_Name:password@host_ftp/Nome_do_arquivo.xls");
url.getHost();
url.getFile();
url.getPort();
url.getUserInfo();
URLConnection con = url.openConnection();
buf = new BufferedInputStream(con.getInputStream());
out = new FileOutputStream("c:\\excelDown.xls");
int i = 0;
byte[] bytesIn = new byte[1024];
while ((i = buf.read(bytesIn)) >= 0) {
out.write(bytesIn, 0, i);
}
ok = true;
} catch (MalformedURLException ex) {
Logger.getLogger(TesteDownloadArqExcel.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ioe) {
Logger.getLogger(TesteDownloadArqExcel.class.getName()).log(Level.SEVERE, null, ioe);
} finally {
try {
if (buf != null) {
buf.close();
}
if (out != null) {
out.close();
}
} catch (IOException ex) {
Logger.getLogger(TesteDownloadArqExcel.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (ok) {
return ok;
}
return false;
}
}
Ao executar o metodo “con.getInputStream()” estou recebendo uma Exception: “java.net.SocketException: Connection reset”
Alguém poderia me dizer o que estou fazendo de errado?
Desde já grato pela atenção.
FTP é um protocolo. Para que você baixe o arquivo você precisa fazer a requisição (assim como em HTTP, quando você faz um GET ou um POST).
Não basta tentar baixar diretamente. A Apache tem uma API para trabalhar com FTP, talvez seja melhor procurar sobre ela.
Ainda estou tendo problemas, dei uma olhada na documentação “org.apache.commons.net.ftp.FTPClient”, mas ainda está ocorrendo a SocketException.
Modifiquei o codigo do método da classe.
private static boolean downloadArquivoExcel() {
BufferedInputStream buf = null;
FileOutputStream out = null;
FTPClient ftpCliente = new FTPClient();
boolean ok = false;
try {
ftpCliente.connect("ftp.nome_servidor.com");
//Verifica se a conectou
if (FTPReply.isPositiveCompletion(ftpCliente.getReplyCode())) {
ftpCliente.login("UserName", "Password");
ftpCliente.setFileType(FTPClient.STREAM_TRANSFER_MODE);
//Desativa a verificação de HOST
ftpCliente.setRemoteVerificationEnabled(false);
out = new FileOutputStream("c:\\excelDown.xls");
buf = new BufferedInputStream(ftpCliente.retrieveFileStream("/excelDown.xls"));
//Verifica se download completou
if (ftpCliente.completePendingCommand()) {
int i = 0;
byte[] bytesIn = new byte[1024];
while ((i = buf.read(bytesIn)) >= 0) {
out.write(bytesIn, 0, i);
}
ok = true;
}
} else {
ftpCliente.disconnect();
Logger.getLogger(TesteDownloadArqExcel.class.getName()).log(Level.SEVERE, "Não foi possível conectar no servidor FTP para atualização da base estática.");
}
} catch (IOException ioe) {
Logger.getLogger(TesteDownloadArqExcel.class.getName()).log(Level.SEVERE, null, ioe);
} finally {
try {
if (ftpCliente != null) {
ftpCliente.disconnect();
}
if (buf != null) {
buf.close();
}
if (out != null) {
out.close();
}
} catch (IOException ex) {
Logger.getLogger(TesteDownloadArqExcel.class.getName()).log(Level.SEVERE, null, ex);
}
}
if (ok) {
return ok;
}
return false;
}
}
O método de verifcação de HOST já ativei e desativei e continua o problema.
Alguém poderia me ajudar com esse código?
Por favor…
[quote=marcobiscaro2112]3 coisas:
-
Você tem certeza que o servidor está OK? Você consegue resgatar esse arquivo se você abrir a linha de comando e se conectar ao servidor?
-
Em que linha exatamente está ocorrendo a exceção?
-
O FTPClient já está em modo passivo por padrão? Se não estiver, deve estar.[/quote]
Resposta:
1 - A linha do código de demonstração verifica se conectou corretamente. Em debug verifiquei se estava conectando corretamente. Tudo OK.
2 - Na linha 22 está ocorrendo SocketException.
3 - Sim está por default.
Usei uma solução um tanto quanto grosseira.
Como meu servidor de aplicativo fica em LINUX, usei o Runtime.getRuntime().exec(“Comando a ser executado”), usando o wget passando a url de conexão com o FTP.
Funcionou mas tive de criar um método para ler o arquivo excel, sendo que tive de temporizar para dar tempo do download ser concluido.
Mas fica o meu problema porque eu acho que isso não é um funcionamento normal.
Isso não é normal mesmo. Coloque aqui o stacktrace completo da exceção e certifique-se que é preciso colocar a barra no início do caminho mesmo (ou se ela pode ser omitida). Além disso, tente realizar outras operações, como listar arquivos (vide documentação: http://commons.apache.org/net/api/org/apache/commons/net/ftp/FTPClient.html) e nos diga o resultado.