2012-09-20 45 views
2

我開發了一個HTTP通信對象,用於通過GET請求下載文件的目的。HTTP GET檢索壓縮文件

這工作得很好,當下載一個文本文件。但是,下載壓縮文件(如zip,gz或tar.gz)似乎可以下載該文件,但文件無效。

在這種情況下,我得到一個meesage說,它試圖在文件開始之前移動指針。 在.tar.gz的情況下,消息是file.tar中的數據錯誤。文件已損壞。

在所有情況下,我使用的下載鏈接都允許從URL完整正確地下載。然而,基於Java代碼的下載將文件關閉,但它無效。

的代碼如下:

public class HTTPCommunicationGet { 

    private URIBuilder sendData; 
    private URI target; 
    private HttpGet getConnection; 

    public HTTPCommunicationGet(String url, TreeMap<String, String> components) { 
     super(url, components); 
    } 

    public HTTPCommunicationGet(String url, String queryString) { 
     super(url, queryString); 
    } 

    protected void defineSendData() throws URISyntaxException, IOException { 
     this.sendData = new URIBuilder(new URI(this.getUrl())); 
     if (this.getComponents() != null && this.getComponents().size() > 0) { 
      for (Map.Entry<String, String> component : this.getComponents().entrySet()) { 
       this.sendData.setParameter(component.getKey(), component.getValue()); 
      } 
     } 
    } 

    protected void retrieveRemoteData() throws IOException, MalformedURLException, URISyntaxException, DataMapHTTPGetException { 

     this.target = this.sendData.build(); 
     this.getConnection = new HttpGet(target); 
     HttpResponse response = client.execute(this.getConnection); 
     if (response.getStatusLine().toString().toUpperCase().contains("200 OK")) { 
      this.setResponse(response.getStatusLine().toString(), "Data Retrieved"); 
      BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
      String line = ""; 
      while ((line = rd.readLine()) != null) { 
       this.remoteData.append(line); 
      } 
     } else { 
      String message = String.format("%s: Provider connection exception; response returned was not 200 OK", this.target.toASCIIString()); 
      this.setResponse(response.getStatusLine().toString(), message); 
      DataMapHTTPGetException ex = new DataMapHTTPGetException(target.toString(), message); 
      throw ex; 
     } 
    } 

    public void downloadFiles(String localFile) throws DataMapConnectionException, FileNotFoundException, IOException, URISyntaxException { 
     // check that we have remoteData set 
     this.defineSendData(); 
     this.retrieveRemoteData(); // everything is bubbled up to the controller class that is calling this. 

     File localMetaFile = new File(localFile); 
     switch (this.archiveMetaFile(localMetaFile)) { 
      case -1: 
       IOException ex = new IOException(String.format("The file %s could not be moved", localFile)); 
       throw ex; 
      //break; 
      case 0: 
       infoLog.info(String.format("%s: this file did not already exist", localFile)); 
       break; 
      case 1: 
       infoLog.info(String.format("%s: this file was found and successfully archived to the processed directory", localFile)); 
       break; 
     } 

     BufferedWriter fileWriter = new BufferedWriter(new FileWriter(localFile)); 
     fileWriter.write(this.remoteData.toString()); 
     fileWriter.close(); 
    } 
} 

正如你可以看到這是通過downloadFiles調用的對象已經被初始化之後。我剪掉了這個例子中不需要的代碼,比如archiveMetaFile方法。

任何指針爲什麼這不適用於壓縮文件非常感謝。

乾杯 彌敦道

+1

「response.getStatusLine()的toString()toUpperCase()包含(」 200 OK 「)」 - 不要做;原因詞組不需要是「OK」。出於某種原因,響應具有整數狀態代碼獲取器。 –

+0

Upvote的評論 - 不是真正的問題,但出色的幫助 - 謝謝。以後你可能會挽救麻煩的世界。 – nathj07

回答

6

的問題可能是你使用的是​​,而不是一個InputStream。讀取器用於文本數據並施加字符編碼,而InputStreams可以處理原始二進制數據。

嘗試改用BufferedInputStream代替。任何Reader類的使用都會破壞二進制數據。

+0

太棒了!非常感謝你做的這些。我現在已經實施了這些改變,並且所有工作都很好。這當然是一些知識,一次又一次地鎖定和使用。由於有關BufferedReader和二進制數據的額外信息,所以接受並接受了upvote。 – nathj07