2

在尝试从像下面的代码那样从 BLOB 获得的 InputStream 中读取时,InputStream 进入无限期等待状态。

我从运行在 Jboss 应用服务器上的 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

但是,如果我尝试在卡盘中读取如下内容.. 它可以正常工作,因为我正在读取序列化对象并希望从 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
4

1 回答 1

1

InputStream.available()并不表示您可以读取多少,它表示它可以返回给您多少(例如从缓冲区),而不会进入 - 潜在的 - 阻塞读取操作。

Javadoc 还指出:

请注意,虽然 InputStream 的某些实现会返回流中的字节总数,但许多不会。使用此方法的返回值来分配旨在保存此流中所有数据的缓冲区是不正确的。

InputStream 类的可用方法总是返回 0。

因此,不要available()用作任何指示,只需阅读它(这显然可以按照您的其他代码所示工作)。

于 2012-09-11T18:34:49.390 回答