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

升级docker-java到3.2.7版本如何获取容器运行命令的实时输出InputStream

docker-java 3.2.7版本attachContainerCmd适配方案

问题原因

docker-java从3.x版本开始重构了流式操作的实现逻辑:

  • 无参exec()方法不再返回InputStream,改为void类型
  • 旧版AttachContainerResultCallback已被废弃,官方推荐使用通用的ResultCallback接口处理流式返回
  • 之前的代码报错是因为带回调参数的exec()本身返回void,无法直接赋值给InputStream类型变量,同时回调类类型不匹配

方案1:通过管道流桥接获取InputStream(适配原有业务逻辑)

如果你的业务逻辑强依赖InputStream输入流,可以通过Piped流对回调输出做桥接,示例代码如下:

import com.github.dockerjava.api.async.ResultCallback;
import com.github.dockerjava.api.model.Frame;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;

// 初始化管道流
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream response = new PipedInputStream(pos);

dockerClient.attachContainerCmd(container.getId())
    .withLogs(true)
    .withStdErr(true)
    .withStdOut(true)
    .withFollowStream(true)
    .exec(new ResultCallback.Adapter<Frame>() {
        @Override
        public void onNext(Frame frame) {
            try {
                // 将容器输出的帧内容写入管道输出流
                pos.write(frame.getPayload());
                pos.flush();
            } catch (Exception e) {
                onError(e);
            }
        }

        @Override
        public void onComplete() {
            try {
                pos.close();
            } catch (Exception e) {
                // 处理流关闭异常
            }
            super.onComplete();
        }

        @Override
        public void onError(Throwable throwable) {
            try {
                pos.close();
            } catch (Exception e) {
                // 忽略关闭异常
            }
            super.onError(throwable);
        }
    });

// 后续可以正常使用response这个InputStream读取输出,注意读取操作要放在独立线程,避免阻塞回调线程

注意事项:

  • 管道流的读写要放在不同线程,否则会出现死锁
  • 要做好异常场景下的流关闭操作,避免资源泄漏

方案2:直接通过回调实现实时输出(推荐)

你的场景需要实时展示容器输出,直接用回调处理更简单,不需要额外维护输入流,示例代码如下:

dockerClient.attachContainerCmd(container.getId())
    .withLogs(true)
    .withStdErr(true)
    .withStdOut(true)
    .withFollowStream(true)
    .exec(new ResultCallback.Adapter<Frame>() {
        @Override
        public void onNext(Frame frame) {
            // 直接将帧内容转为字符串,推送给展示层
            String output = new String(frame.getPayload(), java.nio.charset.StandardCharsets.UTF_8);
            // 这里补充你的实时展示逻辑
            System.out.print(output);
        }

        @Override
        public void onError(Throwable throwable) {
            // 处理执行异常,返回错误提示
            throwable.printStackTrace();
        }

        @Override
        public void onComplete() {
            // 容器执行结束,处理收尾逻辑,比如发送结束通知
        }
    });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 12:15:04