You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法将Telegram Bot接收到的照片以字节数组形式存入数据库

Java Telegram Bot 接收照片转字节数组存入数据库实现方案

核心实现步骤

1. 优化照片尺寸选择

你当前代码直接取photo.get(0)获取的是最低分辨率的照片,建议优先取最大分辨率的版本:

// 取分辨率最高的照片
PhotoSize largestPhoto = update.getMessage().getPhoto().stream()
        .max(Comparator.comparing(PhotoSize::getFileSize))
        .orElseThrow(() -> new RuntimeException("未获取到有效照片"));
GetFile getFile = new GetFile();
getFile.setFileId(largestPhoto.getFileId());

2. 下载文件并转为字节数组

使用try-with-resources自动关闭流,避免资源泄漏,有两种常用实现方式:

方式1:JDK原生实现(无需额外依赖)

byte[] photoBytes;
try (InputStream inputStream = new FileInputStream(getFileRequest(getFile))) {
    photoBytes = inputStream.readAllBytes(); // JDK 9+ 支持
} catch (IOException e) {
    // 自定义异常处理逻辑,比如记录日志、回复用户上传失败
    throw new RuntimeException("照片读取失败", e);
}

如果是JDK 8版本,替换readAllBytes的逻辑:

ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[1024];
try (InputStream inputStream = new FileInputStream(getFileRequest(getFile))) {
    while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
        buffer.write(data, 0, nRead);
    }
    buffer.flush();
    photoBytes = buffer.toByteArray();
} catch (IOException e) {
    throw new RuntimeException("照片读取失败", e);
}

方式2:使用Apache Commons IO工具类(需要引入依赖)

<!-- pom.xml 引入依赖 -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.15.1</version>
</dependency>

转字节数组代码:

byte[] photoBytes;
try (InputStream inputStream = new FileInputStream(getFileRequest(getFile))) {
    photoBytes = IOUtils.toByteArray(inputStream);
} catch (IOException e) {
    throw new RuntimeException("照片读取失败", e);
}

3. 字节数组存入数据库

  • 数据库字段选择:MySQL建议使用MEDIUMBLOB(最大支持16MB)或LONGBLOB(最大支持4GB),避免普通BLOB最大64KB的限制存不下高清照片
  • JDBC存入示例:
// 假设表结构为 CREATE TABLE tg_photos (chat_id BIGINT, photo BLOB, upload_time DATETIME)
String sql = "INSERT INTO tg_photos(chat_id, photo, upload_time) VALUES (?, ?, NOW())";
try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
    pstmt.setLong(1, chatId);
    pstmt.setBytes(2, photoBytes);
    pstmt.executeUpdate();
} catch (SQLException e) {
    throw new RuntimeException("照片存入数据库失败", e);
}

完整修正后的代码示例

public void onUpdateReceived(Update update) {
    this.responseText = "Kerakli bo'limni tanlang:";
    if (update.hasMessage() && update.getMessage().hasPhoto()) {
        this.chatId = update.getMessage().getChatId();
        SendMessage sendMessage = new SendMessage();
        try {
            // 1. 取最大分辨率照片
            PhotoSize largestPhoto = update.getMessage().getPhoto().stream()
                    .max(Comparator.comparing(PhotoSize::getFileSize))
                    .orElseThrow(() -> new RuntimeException("无效照片"));
            // 2. 获取文件
            GetFile getFile = new GetFile();
            getFile.setFileId(largestPhoto.getFileId());
            File file = getFileRequest(getFile);
            // 3. 转字节数组
            byte[] photoBytes;
            try (InputStream inputStream = new FileInputStream(file)) {
                photoBytes = inputStream.readAllBytes();
            }
            // 4. 存入数据库
            String sql = "INSERT INTO tg_photos(chat_id, photo, upload_time) VALUES (?, ?, NOW())";
            try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
                pstmt.setLong(1, chatId);
                pstmt.setBytes(2, photoBytes);
                pstmt.executeUpdate();
            }
            // 回复用户上传成功
            sendMessage.setChatId(chatId);
            sendMessage.setText("照片上传成功");
            execute(sendMessage);
        } catch (Exception e) {
            // 异常处理,回复用户失败
            sendMessage.setChatId(chatId);
            sendMessage.setText("照片上传失败,请重试");
            try {
                execute(sendMessage);
            } catch (TelegramApiException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        }
    }
}

注意事项

  • 若照片文件过大,建议先做压缩处理再存入数据库,降低存储成本
  • 生产环境建议不要直接把文件存在数据库,可存到对象存储服务,数据库只存文件访问链接即可,性能更好
  • 所有IO和数据库操作都要做好异常捕获处理,避免程序崩溃

内容的提问来源于stack exchange,提问作者Shahzodbek Pulatbekov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 07:51:02