尝试从类似下面的BLOB获取的InputStream读取时,InputStream进入无限期等待状态。
我从在Jboss app服务器上运行的Web应用程序设置这些数据并且读/写工作绝对正常,问题在于使用普通JDBC运行独立的Java代码。
环境是JDK6,Oracle 10g。
ResultSet rs = this.stmt.executeQuery();
log.println("ResultSetType: " + (rs != null ? rs.getClass() : null));
while (rs != null && rs.next()) {
. . . // read other columns
Blob savedBlob = rs.getBlob("PERSISTENCE_BLOB");
long len = savedBlob.length();
log.println("Going to read bytes..." + len);
InputStream is = savedBlob.getBinaryStream();
log.println("IS Received...");
log.println("Available : " + is.available());
ObjectInputStream oip = new ObjectInputStream(is);
Object obj = oip.readObject();
oip.close();
is.close();
savedBlob.free();
. . .
输出如下......
ResultSetType: class oracle.jdbc.driver.OracleResultSetImpl
RowID: XXXXXXXXXXXXXXX // Row is selected and printed properly
Going to read bytes...6022
IS Received...
Available : 0
但是,如果我尝试在chucks中阅读如下...它工作正常,我不想要因为我正在读取序列化对象并希望从InputStream中打开ObjectInputStream。
. . .
ResultSet rs = this.stmt.executeQuery();
log.println("ResultSetType: " + (rs != null ? rs.getClass() : null));
while (rs != null && rs.next()) {
. . .
Blob savedBlob = rs.getBlob("PERSISTENCE_BLOB");
long len = savedBlob.length();
int start = 1;
int totalBytesRead = 0;
int buffSize = 2048;
byte[] byteBuff = null;
log.println("Going to read bytes..." + len);
do {
byteBuff = new byte[buffSize];
byteBuff = savedBlob.getBytes(start, buffSize);
totalBytesRead += buffSize;
log.println(start + "," + buffSize + " #BLOB bytes: " + new String(byteBuff));
start += buffSize;
. . .
} while (. . . );
log.println("Total Bytes: " + totalBytesRead);
输出:
ResultSetType: class oracle.jdbc.driver.OracleResultSetImpl
Going to read bytes...6022
1,2048 #BLOB bytes: //......bytes data..........
.....
Total Bytes: 6022
答案 0 :(得分:1)
InputStream.available()
并不表示你可以阅读多少,它表示它可以返回多少(例如从缓冲区),而不会进入 - 可能 - 阻塞读取操作。
Javadoc还表示:
请注意,虽然InputStream的某些实现将返回 流中的总字节数,很多都不会。永远不会 正确使用此方法的返回值来分配缓冲区 旨在保存此流中的所有数据。
和
类InputStream的可用方法始终返回0.
因此,不要使用available()
作为任何形式的指示,只需阅读它(显然可以按照其他代码的说明运行)。