2012-06-06 94 views
0

我必須調用一個以XML格式返回大量數據的休息Web服務。數據大小約爲490米。每次我嘗試撥打服務時,都會耗盡內存。我想要做的就是將這些數據寫入一個文件。如何使用Java從Web服務保存大文件?

有沒有辦法以小塊讀取和寫入數據以避免內存不足?

這是我試過的;

public class GetWs { 

    private static String url ="http://somewebservice"; 
    public static void main(String[] args) { 

    InputStream in; 
    OutputStream out; 
    try { 
      out = new FileOutputStream("testoutfile.txt"); 
      in = new URL(url).openStream(); 
      int b; 
      do { 
       b = in.read(); 
       if (b != -1) { 
      out.write(b); 
       out.flush(); 
       } 
      } while (b != -1); 
      in.close();out.close();  
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

    } 

} 
+0

您使用的框架是否允許您即時生成XML? – Sam

+0

如何從Web服務中讀取數據?請顯示一些代碼。 –

+0

我添加了我正在使用的代碼 – John

回答

2

嘗試壓縮和流式傳輸到文件輸出流,最好使用NIO。

如果您必須解析和驗證XML,請嘗試使用STAX解析器。

+0

值得注意的是,在壓縮時你必須吃減壓。 – Woot4Moo

+0

如果以壓縮格式將它寫入文件,則不行。 – duffymo

+0

我想我假設他會在文件下載完成後用文件做一些事情。 – Woot4Moo

1

如果你真的只是使用InputStream中只使用

byte[] buff = new byte[5000]; 
int num = 1; 
while(num>1){ 
    num = inputStream.read(buff); 
    outputStream.write(buff,0,num); 
} 

雖然你需要添加一些代碼,當你點擊一個文件的末尾檢測~~~(InputStream的依賴性implentation)~~ 〜編輯不,你不會和固定的一些代碼

+1

這段代碼不正確,它在寫入'outputStream'時忽略'read()'讀取的字節數。此外,檢測EOF不依賴於正在使用的具體'InputStream','read()'在EOF上始終返回-1。 –

+0

不好意思退貨狀態。修正了愚蠢的長度錯誤。 – yasth

2

如果你真的只想要那個URL的內容下載到一個文件,試圖Google Guava和它的真棒輔助方法:

URL url = ... 
File file = ... 
ByteStreams.copy(
    Resources.newInputStreamSupplier(url), 
    Files.newOutputStreamSupplier(file)); 

這使您不必再編寫另一個具有適當異常處理的副本循環。甚至沒有必要關閉任何流,ByteStreams.copy()爲你做。

如果您想將數據存儲爲UTF-16,使用這樣的:

Charset charsetFromServer = ...; // See notes below. 

CharStreams.copy(
    Resources.newReaderSupplier(url, charsetFromServer), 
    Files.newWriterSupplier(file, Charsets.UTF_16)); 

有幾種方法來設置charsetFromServer

  • 如果你可以信任的服務器總是使用相同的字符集,通過使用Charset.forName(String)或Guava的Charsets類中的常量之一手動設置它。確實,確定服務器永遠不會使用任何其他編碼,否則這將會中斷。

  • 更詳細的方法是通過查看Content-Type標頭來確定服務器在運行時使用的字符編碼。我建議你看一下how Apache's HttpClient是做還是隻用HttpClient開始,這就像ContentType.getOrDefault(response.getEntity()).getCharset()一樣簡單。

+0

這會處理大文件而不填滿內存嗎? – John

+0

是的,其內存消耗與正在複製的數據量無關。只要有足夠的磁盤空間來寫入文件,應該沒有內存問題。 –

+0

我怎樣才能得到這個寫一個UTF-16輸出文件? – John