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 の available メソッドは、常に 0 を返します。

available()したがって、何らかの指示として使用する代わりに、それを読んでください(他のコードで示されているように明らかに機能します)。

于 2012-09-11T18:34:49.390 に答える