【问题标题】:IOUtils.toByteArray is returning empty byte arrayIOUtils.toByteArray 正在返回空字节数组
【发布时间】:2018-07-10 14:30:45
【问题描述】:

我是 Java 开发的新手,所以如果我问一些愚蠢的问题,请提前道歉。

我正在尝试从 sql 数据库中检索图像和缩略图。 我从ResultSet 获取BinaryStream 格式的数据,然后将其转换为byte[]

对于缩略图,它可以正常工作,对于原始图像,我也可以使用 getBinaryStream 方法检索 BinaryStream但是当我将其转换为 byte[] 时,数组仍然为空出于某种原因

binaryStream = rs.getBinaryStream("image");
thumbBinaryStream = rs.getBinaryStream("thumbnail");
if (binaryStream != null) {
    // Tested on following line and I get empty imageBytes
    byte[] imageBytes = IOUtils.toByteArray(binaryStream); 
    thisRecord.put("image", DatatypeConverter.printBase64Binary(imageBytes)); // imageBytes is empty here 
}

【问题讨论】:

  • 为什么要使用 InputStream 呢?为什么不打电话给ResultSet.getBytes?如byte[] imageBytes = rs.getBytes("image");?
  • 我已经尝试了两种方法,但imageBytes 仍然为空,而如果我对thumbBinaryStream 执行相同操作并将其转换为字节,我会得到数据。

标签: java sql arrays binarystream ioutils


【解决方案1】:

我们可能需要更多信息,尤其是有关列的数据类型的信息,但可能有助于从 BLOB 中检索流,如下例所示:

if (rs.getMetaData().getColumnType(column) == Types.BLOB) {
        in = rs.getBlob(column).getBinaryStream();
    } else {
        in = rs.getBinaryStream(column);
    }

【讨论】:

  • thumbnail 和 image 都是 LONGBLOB 并且是完全相同的类型。但问题是它对一个人有效,对另一个人无效。
  • 对于大的二进制数据,建议从getBlob(columnName)的结果中检索流,所以你应该尝试一下。否则检查是否有数据?
  • 我通过简单地运行查询进行了检查,BLOB 就在那里。我试过用 BLOB 但没有改变。我很惊讶为什么我使用相同的代码从缩略图列中获取数据。
【解决方案2】:

确定: Statement 和 ResultSet 必须关闭,getBinaryStream 仅在 ResultSet 仍处于打开状态时使用,例如:

try (ResultSet rs = stmt.executeQuery()) {
    while (rs.next()) {
        InputStream binaryStream = rs.getBinaryStream("image");
        InputStream thumbBinaryStream = rs.getBinaryStream("thumbnail");
        if (binaryStream != null) {
            // Tested on following line and I get empty imageBytes
            byte[] imageBytes = IOUtils.toByteArray(binaryStream); 
            thisRecord.put("image", DatatypeConverter.printBase64Binary(imageBytes));
            boolean mustGenerateThumbnail = thumbBinaryStream == null;
            if (mustGenerateThumbnail ) {
                thumbBinaryStream = generateThumbnail(imageBytes);
            }
            byte[] thumbBytes = IOUtils.toByteArray(thumbBinaryStream);
            thisRecord.put("thumbnail", DatatypeConverter.printBase64Binary(thumbBytes));

这里我们遇到了错误。此时 thumbBinaryStream 被读取到最后,所以这样做:

            if (mustGenerateThumbnail ) {
                ByteArrayInputStream baIn = new ByteArrayInputStream(thumbBytes);
                saveThumbnailForRecordWithId(baIn, floor_drawing_id);
            }
        }
    }
}

(这里我使用 try-with-resources 来自动关闭 ResultSet,即使抛出异常。)

此外,Base64 还有一个更通用的类。如果您将来有这样的需要。

DatatypeConverter.printBase64Binary(thumbBytes)
Base64.getEncoder().encodeToString(thumbBytes)

【讨论】:

  • 我已经更新了我的代码,以便您更清楚地了解我的问题。对不起,我之前添加了不相关的代码。
  • 而且 ResultSet rs 似乎仍然打开。可能没有拇指只给出一个空(非空)InputStream,导致零字节。
  • 我在尝试获取缩略图时获取数据,但在尝试获取图像时获取空字节数组。所以byte[] thumbBytes = IOUtils.toByteArray(thumbBinaryStream); 这工作正常,而byte[] imageBytes = IOUtils.toByteArray(binaryStream); 这不行。我确信数据在数据库中。我在两个字段中都以相同的方式插入数据。
  • 我开始怀疑generateThumbnail,因为其余的代码是合理的。很抱歉在这里没有帮助。
猜你喜欢
  • 2012-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-23
  • 2016-06-01
  • 1970-01-01
相关资源
最近更新 更多