当前位置: 首页 > 面试题库 >

如何解压通量 (以及如何写一个)?

司马璞
2023-03-14
问题内容

我需要在没有中间存储的情况下读写压缩(GZIP)流。目前,我正在使用Spring RestTemplate进行编写,而使用Apache
HTTP客户端来进行阅读的答案,以解释为什么RestTemplate不能用于读取大数据流)。实现是相当简单的,我GZIPInputStream在响应上打了一下InputStream然后继续。

现在,我想切换到使用Spring 5
WebClient(只是因为我不喜欢现状)。但是,WebClient本质上是反应性的,并且要处理Flux<Stuff>;我相信有可能获得Flux<DataBuffer>,其中DataBuffer是的抽象ByteBuffer。问题是,如何在不将整个流存储到内存(OutOfMemoryError我在看着你)或写入本地磁盘的情况下即时对其进行解压缩?值得一提的是WebClient在后台使用Netty。

  • 另请参见Reactor Netty 问题251。
  • 还与Spring Integration issue-2300有关。

问题答案:

public class HttpResponseHeadersHandler extends ChannelInboundHandlerAdapter {
private final HttpHeaders httpHeaders;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        if (msg instanceof HttpResponse &&
                !HttpStatus.resolve(((HttpResponse) msg).status().code()).is1xxInformational()) {
            HttpHeaders headers = ((HttpResponse) msg).headers();

            httpHeaders.forEach(e -> {
                log.warn("Modifying {} from: {} to: {}.", e.getKey(), headers.get(e.getKey()), e.getValue());
                headers.set(e.getKey(), e.getValue());
            });
        }
        ctx.fireChannelRead(msg);
    }
}

然后,我创建一个和ClientHttpConnector一起使用WebClientafterNettyContextInit添加处理程序:

ctx.addHandlerLast(new ReadTimeoutHandler(readTimeoutMillis, TimeUnit.MILLISECONDS));
ctx.addHandlerLast(new Slf4JLoggingHandler());
if (forceDecompression) {
    io.netty.handler.codec.http.HttpHeaders httpHeaders = new ReadOnlyHttpHeaders(
            true,
            CONTENT_ENCODING, GZIP,
            CONTENT_TYPE, APPLICATION_JSON
    );
    HttpResponseHeadersHandler headersModifier = new HttpResponseHeadersHandler(httpHeaders);
    ctx.addHandlerFirst(headersModifier);
}
ctx.addHandlerLast(new HttpContentDecompressor());

当然,对于未经GZIP压缩的响应,这将失败,因此,我WebClient仅在特定的用例中使用此的实例,在这种情况下,我确定响应是压缩的。

编写很容易:Spring有一个ResourceEncoder,因此InputStream可以简单地转换为InputStreamResource,瞧!



 类似资料:
  • 我需要在没有中间存储的情况下读写压缩(GZIP)流。目前,我使用Spring

  • 我在资产文件夹中有一个.apk文件。我想解压缩那个.apk文件并在其中插入一个文件,然后从移动端生成一个.apk。我怎样才能实现呢?给出任何建议。

  • 问题内容: 我希望能够使用创建存储过程,以后再通过php使用它。 但是我不知道该怎么办? 据我了解,我发现我们无法通过来管理存储过程。 还有什么其他工具可以管理存储过程? 我什至不确定通过PHP使用存储过程是否是更好的选择。 有什么建议吗? 问题答案: 由于使用查询创建,更改和删除了存储过程,因此您实际上可以使用phpMyAdmin对其进行管理。 要创建存储过程,可以使用以下命令(必要时进行更改)

  • 我使用LZMA SDK在Windows7(64位)下进行文件压缩/解压缩(LZMA是7-zip中使用的默认算法)。 sdk可以在这里找到(源代码)http://7-zip.org/sdk.html 以加快闪烁过程。我想做增量压缩来分离文件,以获得更小的大小。然而,我想用增量解压缩来解压缩文件,这样第一部分被解压缩,而其他部分来自can总线。 所以在MCU部分,我想要能够一个部分一个部分的解压和闪存

  • 假设我有两个外部服务。假设我们有一个item,serviceA返回item,serviceB返回item。 我想要得到的是形式的处理程序,其中和是同一查询项的对应对象。 是迄今为止我找到的最接近的东西,但它不是我想要的东西,因为订单没有promise。我在寻找像CompletableFuture::allOf这样的东西 我总是可以通过使这两个调用同步来作弊,但这会让反应式编程失去所有乐趣。或者,我

  • 上次分析了背后的一些原因,这次说说如何应对 首先这里默认没有任何挽回机会了,而不是你跪在女神面前大哭一场,或作出一哭二闹三上吊这种夸张的事情便可力挽狂澜的 如果你真做了,并且挽回了,那么请参考如何恋爱的番外,而非下文 对于个体而言,如何尽快走出困境,把损失降到最低,这是我们现在最为关心的 好,我们先来处理《黄帝内经》中着重强调的“治未病”阶段 首先,要正视自己的备胎身份 大多数人往往不愿意承认这个