2012-06-09 6 views
26

Sto tentando di scaricare un file PDF con HttpClient. Sono in grado di ottenere il file ma non sono sicuro di come convertire i byte in un PDF e di memorizzarlo da qualche parte sul sistemaCome salvare un file scaricato con HttpClient in una cartella specifica

Ho il seguente codice, Come posso archiviarlo come PDF?

public ???? getFile(String url) throws ClientProtocolException, IOException{ 

      HttpGet httpget = new HttpGet(url); 
      HttpResponse response = httpClient.execute(httpget); 
      HttpEntity entity = response.getEntity(); 
      if (entity != null) { 
       long len = entity.getContentLength(); 
       InputStream inputStream = entity.getContent(); 
       // How do I write it? 
      } 

      return null; 
     } 

risposta

33
InputStream is = entity.getContent(); 
String filePath = "sample.txt"; 
FileOutputStream fos = new FileOutputStream(new File(filePath)); 
int inByte; 
while((inByte = is.read()) != -1) 
    fos.write(inByte); 
is.close(); 
fos.close(); 

EDIT:

è possibile anche utilizzare BufferedOutputStream e BufferedInputStream per il download più veloce:

BufferedInputStream bis = new BufferedInputStream(entity.getContent()); 
String filePath = "sample.txt"; 
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(filePath))); 
int inByte; 
while((inByte = bis.read()) != -1) bos.write(inByte); 
bis.close(); 
bos.close(); 
+6

HttpClient ottimizza internamente le operazioni di lettura. Non è necessario utilizzare un altro strato di buffer – oleg

+0

Impossibile scrivere direttamente sul percorso di quel file, ho dovuto usare 'File file = nuovo File (context.getExternalFilesDir (Environment.DIRECTORY_DOWNLOADS)," filename.jpg ");' per scrivendo su un dispositivo di archiviazione esterno, in modo che altre app possano vedere la mia app – Aaron

1

Aprire un FileOutputStream e salvare il byte da inputStream ad esso.

+0

Quello che mi confonde è che si dispone di un FileOutputStream già aperto nel metodo downloadAndSaveToFile, ma quando creo l'oggetto File con il percorso completo, ho ottenere un 'file non esiste' errore ... si può mostrare noi codice che prenderebbe questo file che è stato scaricato e salvarlo in una cartella specifica? –

+0

Mi scuso, ho avuto un refuso nel mio percorso. Come risulta, posso specificare l'oggetto file con il percorso completo desiderato quando il percorso è un percorso VALID. :-) –

21

Ecco una soluzione semplice utilizzando IOUtils.copy():

File targetFile = new File("foo.pdf"); 

if (entity != null) { 
    InputStream inputStream = entity.getContent(); 
    OutputStream outputStream = new FileOutputStream(targetFile); 
    IOUtils.copy(inputStream, outputStream); 
    outputStream.close(); 
} 

return targetFile; 

IOUtils.copy() è ottimo perché gestisce il buffering. Tuttavia questa soluzione non è molto scalabile:

  • non è possibile specificare il nome del file di destinazione e la directory
  • si potrebbe voler archiviare i file in modo diverso, ad esempio, in un database. I file non sono necessari in questo scenario.

molto più scalabile soluzione prevede due funzioni:

public void downloadFile(String url, OutputStream target) throws ClientProtocolException, IOException{ 
    //... 
    if (entity != null) { 
    //... 
     InputStream inputStream = entity.getContent(); 
     IOUtils.copy(inputStream, target); 
    } 
} 

E un metodo di supporto:

public void downloadAndSaveToFile(String url, File targetFile) { 
    OutputStream outputStream = new FileOutputStream(targetFile); 
    downloadFile(url, outputStream); 
    outputStream.close(); 
} 
+0

In questo flusso il file o tenere l'intero file in memoria e quindi salvare su disco? –

26

Solo per la cronaca ci sono migliori (più facile) modi di fare la stessa

File myFile = new File("mystuff.bin"); 

CloseableHttpClient client = HttpClients.createDefault(); 
try (CloseableHttpResponse response = client.execute(new HttpGet("http://host/stuff"))) { 
    HttpEntity entity = response.getEntity(); 
    if (entity != null) { 
     try (FileOutputStream outstream = new FileOutputStream(myFile)) { 
      entity.writeTo(outstream); 
     } 
    } 
} 

O con l'API fluente se piace a qualcuno meglio

Request.Get("http://host/stuff").execute().saveContent(myFile); 
+2

Il pacchetto Witch deve essere importato per 'Request.Get (" http: // host/stuff ") .execute(). SaveContent (myFile)' – badera

+0

In Maven è necessario l'artefatto 'org.apache.httpcomponents: fluent- hc' - il pacchetto Java è 'org.apache.http.client.fluent.Request' –