文章目录
0. 场景
-
数据库中有个blob字段,存入数据的时候,需要传入相应的InputStream流,而我又需要InputStream流里面的内容判断其他事情。
-
也就是说 一个InputStream 我需要用两次。
public void test(InputStream in){ String sql = "xxxx values(?) xxx"; preparedStatement.setObject(in); execute(); byte[] bufferOne = new byte[1024]; int len = -1; while((len = in.read(bufferOne)) != -1){ xxxx } xxxx 其他逻辑 最后测试发现,下面in.read 读了个寂寞 }
1. 原因
- 经过实际测试得出,InputStream不能读取两次,具体原因是,在读取InputStream的时候,其实内部是有个指针,它指示每次读取之后下一次要读取的起始位置,当你第一次读完的时候,指针已经指到最后了,当你再次读取的时候,自然是读不到数据的。
2. 现象重现
public class demo_InputStream {
public static void main(String[] args) throws Exception{
InputStream is = demo_InputStream.class.getResourceAsStream("test.txt");
byte[] buffer = new byte[1024];
int len = -1;
while((len = is.read(buffer)) != -1){
System.out.println(new String(buffer,0, len));
}
System.out.println("-------------------");
byte[] buffer2 = new byte[1024];
len = -1;
while((len = is.read(buffer2)) != -1){
System.out.println(new String(buffer2,0, len));
}
is.close();
}
}
3. 解决方法
1. 使用String字符串保留InputStream的内容
public class correctOne_InputStream {
public static void main(String[] args) throws Exception {
InputStream is = correctOne_InputStream.class.getResourceAsStream("test.txt");
// builder 保留读到的数据
StringBuilder builder = new StringBuilder();
byte[] buffer = new byte[1024];
int len = -1;
while((len = is.read(buffer)) != -1){
builder.append(new String(buffer, 0 ,len));
}
System.out.println("-------第一次需要InputStream,那么就创建一个-----------");
InputStream isOne = new ByteArrayInputStream(builder.toString().getBytes());
// 下面是测试新的InputStream到底是否有数据
byte[] bufferOne = new byte[1024];
len = -1;
while((len = isOne.read(bufferOne)) != -1){
System.out.println(new String(bufferOne,0, len));
}
System.out.println("-------第二次第一次需要InputStream,那么就再创建一个-----------");
InputStream isTwo = new ByteArrayInputStream(builder.toString().getBytes());
// 下面是测试新的InputStream到底是否有数据
byte[] bufferTwo = new byte[1024];
len = -1;
while((len = isTwo.read(bufferTwo)) != -1){
System.out.println(new String(bufferTwo,0, len));
}
is.close();
isOne.close();
isTwo.close();
}
}
2. 使用ByteArrayOutputStream保留InputStream的内容
public class correctTwo_InputStream {
public static void main(String[] args) throws Exception {
InputStream is = correctTwo_InputStream.class.getResourceAsStream("test.txt");
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
int len;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1) {
byteArrayOut.write(buffer, 0, len);
}
System.out.println("重构一个InputStream");
InputStream isTwo = new ByteArrayInputStream(byteArrayOut.toByteArray());
// 测试新的InputStream到底是否有数据
byte[] bufferTwo = new byte[1024];
len = -1;
while((len = isTwo.read(bufferTwo)) != -1){
System.out.println(new String(bufferTwo,0, len));
}
is.close();
isTwo.close();
}
}
4. 总结
- 总的来说,就是记录下来数据,需要inputStream 重新构建一个。
- 源码地址:https://gitee.com/Lgold/learning/tree/dev/src/main/java/com/king/learning/InputStream