Há um arquivo online (como http://www.example.com/information.asp
) que eu preciso pegar e salvar em um diretório. Eu sei que existem vários métodos para capturar e ler arquivos online (URLs) linha por linha, mas existe uma maneira de baixar e salvar o arquivo usando Java?
425
Respostas:
Experimente o Java NIO :
O uso
transferFrom()
é potencialmente muito mais eficiente do que um loop simples que lê do canal de origem e grava nesse canal. Muitos sistemas operacionais podem transferir bytes diretamente do canal de origem para o cache do sistema de arquivos sem realmente copiá-los.Veja mais aqui .
Nota : O terceiro parâmetro em transferFrom é o número máximo de bytes a serem transferidos.
Integer.MAX_VALUE
transferirá no máximo 2 ^ 31 bytes,Long.MAX_VALUE
permitirá no máximo 2 ^ 63 bytes (maior que qualquer arquivo existente).fonte
8388608
TB?transferFrom()
não está especificado para concluir toda a transferência em uma única chamada. É por isso que retorna uma contagem. Você tem que fazer um loop.URL::openStream()
retorna apenas um fluxo regular, o que significa que todo o tráfego ainda está sendo copiado através de matrizes Java byte [] em vez de permanecer em buffers nativos. Somentefos.getChannel()
é realmente um canal nativo, portanto, a sobrecarga permanece completa. Isso representa zero ganho ao usar o NIO neste caso. Além de estar quebrado, como EJP e Ben MacCann perceberam corretamente.Use o apache commons-io , apenas um código de linha:
fonte
copyURLToFile
parâmetro timeout está disponível apenas desde a versão 2.0 da biblioteca Commons IO. Veja docs JavaUso mais simples do nio:
fonte
InputStream.read()
retornar zero, a menos que você tenha fornecido um buffer ou contagem de comprimento zero, 'pequena pausa' ou não. Ele será bloqueado até que pelo menos um byte seja transferido ou no final do fluxo ou ocorra um erro. Sua reivindicação sobre os internos deFiles.copy()
é infundada.Você precisará lidar com exceções, provavelmente externas a esse método.
fonte
in.close
lança uma exceção,fout.close
não é chamado.BufferedInputStream
tem um efeito exatamente zero nos tempos limite do soquete. Eu já havia refutado isso como "mito urbano" em meus comentários aos "detalhes de fundo" que você citou. Três anos antes.BufferedInputStream
"pode causar falhas imprevisíveis").É uma pergunta antiga, mas aqui está uma solução concisa, legível e somente para JDK com recursos adequadamente fechados:
Duas linhas de código e sem dependências.
fonte
import java.io.InputStream; import java.net.URI; import java.nio.file.Files; import java.nio.file.Paths;
O download de um arquivo requer que você o leia, de qualquer forma, você precisará percorrer o arquivo de alguma maneira. Em vez de linha por linha, você pode simplesmente ler por bytes do fluxo:
fonte
Ao usar,
Java 7+
use o seguinte método para baixar um arquivo da Internet e salve-o em algum diretório:Documentação aqui .
fonte
Essa resposta é quase exatamente igual à resposta selecionada, mas com dois aprimoramentos: é um método e fecha o objeto FileOutputStream:
fonte
transferFrom()
não está especificado para concluir toda a transferência em uma única chamada. É por isso que retorna uma contagem. Você tem que fazer um loop.fonte
in.close
lança uma exceção,out.close
não é chamado.Pessoalmente, achei o HttpClient do Apache mais do que capaz de tudo o que eu precisava fazer com relação a isso. Aqui está um ótimo tutorial sobre o uso do HttpClient
fonte
Esta é outra variante java7 baseada na resposta de Brian Risk com o uso da instrução try-with:
fonte
transferFrom()
não está especificado para concluir toda a transferência em uma única chamada. É por isso que retorna uma contagem. Você tem que fazer um loop.É possível baixar o arquivo com o Apache em
HttpComponents
vez deCommons-IO
. Esse código permite que você baixe um arquivo em Java de acordo com sua URL e salve-o no destino específico.Em contraste com a única linha de código:
este código vai lhe dar mais controle sobre um processo e permitem especificar não apenas os pedidos de tempo, mas
User-Agent
eReferer
valores, que são críticos para muitos web-sites.fonte
Há muitas respostas elegantes e eficientes aqui. Mas a concisão pode nos fazer perder algumas informações úteis. Em particular, geralmente não se deseja considerar um erro de conexão uma exceção e pode-se tratar de forma diferente algum tipo de erro relacionado à rede - por exemplo, para decidir se devemos tentar novamente o download.
Aqui está um método que não lança exceções para erros de rede (apenas para problemas realmente excepcionais, como url malformado ou problemas para gravar no arquivo)
fonte
Abaixo está o código de exemplo para baixar filme da internet com código java:
fonte
Há um problema com o uso simples de:
se você precisar baixar e salvar arquivos muito grandes ou, em geral, se precisar de tentativas automáticas, caso a conexão seja interrompida.
O que eu sugiro nesses casos é o Apache HttpClient junto com org.apache.commons.io.FileUtils. Por exemplo:
fonte
Para resumir (e de alguma forma polir e atualizar) as respostas anteriores. Os três métodos a seguir são praticamente equivalentes. (Adicionei tempos limite explícitos porque acho que eles são obrigatórios, ninguém quer que um download seja congelado para sempre quando a conexão for perdida.)
Não encontro diferenças significativas, tudo parece correto para mim. Eles são seguros e eficientes. (As diferenças de velocidade parecem pouco relevantes - eu escrevo 180 Mb do servidor local em um disco SSD em momentos que variam em torno de 1,2 a 1,5 segs). Eles não exigem bibliotecas externas. Todos trabalham com tamanhos arbitrários e (para minha experiência) redirecionamentos HTTP.
Além disso, todos são lançados
FileNotFoundException
se o recurso não for encontrado (erro 404, normalmente) ejava.net.UnknownHostException
se a resolução do DNS falhar; outra IOException corresponde a erros durante a transmissão.(Marcado como wiki da comunidade, adicione informações ou correções)
fonte
Existe o método U.fetch (url) na biblioteca underscore-java .
pom.xml:
Exemplo de código:
fonte
Java
, mas a sua resposta olhar comoJavaScript
fonte
Você pode fazer isso em 1 linha usando o netloader para Java :
fonte
Se você estiver atrás de um proxy, poderá definir os proxies no programa java como abaixo:
Se você não estiver atrás de um proxy, não inclua as linhas acima no seu código. Código de trabalho completo para baixar um arquivo quando você está atrás de um proxy.
fonte
1º método usando o novo canal
Segundo método usando FileUtils
Terceiro método usando
É assim que podemos baixar o arquivo usando o código java básico e outras bibliotecas de terceiros. Estes são apenas para referência rápida. Pesquise no Google com as palavras-chave acima para obter informações detalhadas e outras opções.
fonte