繁体   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