簡體   English   中英

JAVA使用IOUtils.toString和HttpEntity.getContent()將InputStream轉換為null

[英]JAVA Using IOUtils.toString with HttpEntity.getContent() converting the InputStream to null

我有一個奇怪的senario我有HTTP響應,我嘗試將其轉換為字符串,問題是第一次運行,但第二次InputStream數據為null
而且我只在response1中有數據

InputStream  is = entity.getContent();  
String response1 = IOUtils.toString(is, "utf-8");  // Here every thing is fine 
String respons2 = IOUtils.toString(is, "utf-8");   // Here the response2 is empty 
and is (InputStream) holding no data  

這是什么問題,我需要能夠將數據保存在InputStream中,以備將來在代碼中使用

但是,當檢查javadoc httpEntity.getContent時,您的需求不是很清楚:

返回實體的內容流。 每次此方法的調用,可重復的實體都將創建一個InputStream的新實例,因此可以多次使用。 不可重復的實體應返回相同的InputStream實例,因此消耗的次數不得超過一次。

您是否通過調用檢查httpEntity是否可重復

httpEntity.isRepeatable()

如果為true,則可以執行以下操作:

InputStream  is = entity.getContent();  
String response1 = IOUtils.toString(is, "utf-8");

// retrieve a new instance of inputStream
is = entity.getContent();
String response2 = IOUtils.toString(is, "utf-8");    

最后但並非最不重要的一點(因為我不知道您的確切需求),如果實體能夠多次產生其數據,那么前面的代碼會有所幫助,但是您應該評估以下兩者之間的成本:

  • 一次使用數據並保存為字符串
  • 多次使用數據

不,流不應該被多次讀取。

如果您想保留流的內容以供重復使用,則可以這樣做。 在您的情況下,只需重新使用response1字符串即可。

在閱讀之前,您應該檢查流是否支持重置。 您可以檢查InputStream#markSupported()的結果,該結果告訴您是否可以使用方法對mark()/reset()

如果支持mark,則可以在讀取時執行mark() ,然后reset()返回開始。

如果httpEntity是不可重復的,則可以將InputStream包裹在BufferedInputStream中;否則,可以將InputStream包裝為BufferedInputStream。 這樣,您可以將其重置以允許重新讀取。 本質上,BufferedInputStream第一次將數據讀取到內部緩沖區中,然后在您重新讀取時重新使用該緩沖區。

final int bufferSize = 1_000_000; // about 1 MB; must be large enough to hold all the http content
InputStream  is = new BufferedInputStream(entity.getContent(), bufferSize);
is.mark(bufferSize);
String response1 = IOUtils.toString(is, "utf-8");
is.reset();
String respons2 = IOUtils.toString(is, "utf-8");  

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM