Ren*_*ani 152 java clone inputstream
我有一个InputStream,我传递给一个方法来做一些处理.我将在其他方法中使用相同的InputStream,但在第一次处理之后,InputStream似乎在方法内部关闭.
我如何克隆InputStream发送到关闭他的方法?有另一种解决方案吗?
编辑:关闭InputStream的方法是来自lib的外部方法.我无法控制关闭与否.
private String getContent(HttpURLConnection con) {
InputStream content = null;
String charset = "";
try {
content = con.getInputStream();
CloseShieldInputStream csContent = new CloseShieldInputStream(content);
charset = getCharset(csContent);
return IOUtils.toString(content,charset);
} catch (Exception e) {
System.out.println("Error downloading page: " + e);
return null;
}
}
private String getCharset(InputStream content) {
try {
Source parser = new Source(content);
return parser.getEncoding();
} catch (Exception e) {
System.out.println("Error determining charset: " + e);
return "UTF-8";
}
}
Run Code Online (Sandbox Code Playgroud)
Ant*_*oly 175
如果你想要做的就是多次读取相同的信息,并输入数据是足够小,以适应到内存中,你可以从你的数据复制InputStream到一个ByteArrayOutputStream.
然后,您可以获取相关的字节数组,并根据需要打开尽可能多的"克隆" ByteArrayInputStream.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Fake code simulating the copy
// You can generally do better with nio if you need...
// And please, unlike me, do something about the Exceptions :D
byte[] buffer = new byte[1024];
int len;
while ((len = input.read(buffer)) > -1 ) {
baos.write(buffer, 0, len);
}
baos.flush();
// Open new InputStreams using the recorded bytes
// Can be repeated as many times as you wish
InputStream is1 = new ByteArrayInputStream(baos.toByteArray());
InputStream is2 = new ByteArrayInputStream(baos.toByteArray());
Run Code Online (Sandbox Code Playgroud)
但是,如果您确实需要保持原始流开放以接收新数据,那么您将需要跟踪此外部close()方法并防止以某种方式调用它.
Fem*_*emi 30
你想使用Apache的CloseShieldInputStream:
这是一个阻止流关闭的包装器.你会做这样的事情.
InputStream is = null;
is = getStream(); //obtain the stream
CloseShieldInputStream csis = new CloseShieldInputStream(is);
// call the bad function that does things it shouldn't
badFunction(csis);
// happiness follows: do something with the original input stream
is.read();
Run Code Online (Sandbox Code Playgroud)
您无法克隆它,以及您将如何解决问题取决于数据的来源.
一种解决方案是将InputStream中的所有数据读入字节数组,然后围绕该字节数组创建ByteArrayInputStream,并将该输入流传递给您的方法.
编辑1:也就是说,如果另一种方法也需要读取相同的数据.即你想"重置"流.
这可能无法在所有情况下都起作用,但是这是我所做的:我扩展了FilterInputStream类,并在外部lib读取数据时对字节进行了必要的处理。
public class StreamBytesWithExtraProcessingInputStream extends FilterInputStream {
protected StreamBytesWithExtraProcessingInputStream(InputStream in) {
super(in);
}
@Override
public int read() throws IOException {
int readByte = super.read();
processByte(readByte);
return readByte;
}
@Override
public int read(byte[] buffer, int offset, int count) throws IOException {
int readBytes = super.read(buffer, offset, count);
processBytes(buffer, offset, readBytes);
return readBytes;
}
private void processBytes(byte[] buffer, int offset, int readBytes) {
for (int i = 0; i < readBytes; i++) {
processByte(buffer[i + offset]);
}
}
private void processByte(int readByte) {
// TODO do processing here
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您只需StreamBytesWithExtraProcessingInputStream在输入流中传递一个传递位置的实例。使用原始输入流作为构造函数参数。
应该注意的是,这逐字节工作,因此如果需要高性能,请不要使用它。
更新。检查之前的评论。这不是完全被问到的。
如果您正在使用,apache.commons您可以使用IOUtils.
您可以使用以下代码:
InputStream = IOUtils.toBufferedInputStream(toCopy);
Run Code Online (Sandbox Code Playgroud)
以下是适合您情况的完整示例:
public void cloneStream() throws IOException{
InputStream toCopy=IOUtils.toInputStream("aaa");
InputStream dest= null;
dest=IOUtils.toBufferedInputStream(toCopy);
toCopy.close();
String result = new String(IOUtils.toByteArray(dest));
System.out.println(result);
}
Run Code Online (Sandbox Code Playgroud)
此代码需要一些依赖项:
行家
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
摇篮
'commons-io:commons-io:2.4'
Run Code Online (Sandbox Code Playgroud)
这是此方法的 DOC 参考:
获取 InputStream 的全部内容并表示与结果 InputStream 相同的数据。这种方法在以下情况下很有用,
源 InputStream 很慢。它有关联的网络资源,所以我们不能让它长时间保持打开状态。它具有关联的网络超时。
您可以IOUtils在此处找到更多信息:http :
//commons.apache.org/proper/commons-io/javadocs/api-2.4/org/apache/commons/io/IOUtils.html#toBufferedInputStream(java.io.InputStream)
| 归档时间: |
|
| 查看次数: |
123143 次 |
| 最近记录: |