【问题标题】:Using InputStream/OutputStream to handle data flows through modules使用 InputStream/OutputStream 处理通过模块的数据流
【发布时间】:2013-04-25 01:53:48
【问题描述】:

所以现在我有一堆模块。这就像一条装配线。有数据流过,每个模块对数据做一些事情,或者你可以说下一个模块消耗前一个模块产生的输出。每个模块都被期望是独立的和可重用的。我认为这是一个非常典型的场景。

所以最初我将每个模块的接口设计为模块(InputStream 是,OutputStream os)。因此,它可以将文件(无论来源如何)作为输入和输出。当您想到数据流时,前一个模块的输出流将流向下一个模块的输入流。但后来我意识到 Java 甚至没有一种直观/简单的方法来将数据从 OutputStream 获取到 InputStream。 (注意:这个问题不是关于如何实现这一点。对于那些有兴趣的人, How to convert OutputStream to InputStream?)

在我看来,OutputStream/InputStream 可能不是为了这样的目的。 那么在这种情况下,设计处理数据流的接口的最佳方式是什么?

【问题讨论】:

    标签: java inputstream outputstream dataflow


    【解决方案1】:

    对于离散对象,您可以使用带有 ConcurrentLinkedQueuesBlockingQueues 的生产者/消费者模式 - 每个模块都有自己的队列,并且它将不断地 poll 其队列(或使用 take 如果它是 BlockingQueue) ,处理对象,然后offer 将其放入下一个模块的队列。

    如果您将字节流分块成较小的字节数组并通过队列传递,此模式也可以与字节流一起使用,但这并不总是合适的(例如,如果模块 1 读取、模块 2 压缩和模块 3 加密,那么您除非您有一些合理的方法来分块数据,否则最好将数据保存在流中)。

    【讨论】:

    • 是的,我的情况与 module1 解析、module2 压缩和 module3 加密非常相似。将数据分块以使其适合 ConcurrentLinkedQueues 或 BlockingQueues 模式没有意义。而这一切都是按顺序发生的。简单,因为它不涉及并发。
    • 我肯定会听到并了解更多关于此的信息,但到目前为止,在我看来 InputStream/OutputStream 的设计很糟糕。这将是一种处理数据接口的好方法。
    • 您可以使用IOUtils 中的copy 方法解决此问题,例如copy inputstream to outputstream
    【解决方案2】:

    您可以创建一个实现OutputStreamInputStream 转换的通用模块,并在每个其他模块之间放置一个模块实例。您甚至可以对它感兴趣,并使模块足够智能,以将消息从一个模块路由到任何其他模块。这将成为一种网关或路由器类型的模块。

    或者,您可以使用像ZeroMQ 这样的消息队列和传递框架来实现一些更重的东西。
    --ap

    【讨论】:

    • 把 OutputStream 到 InputStream 的转换作为一个实用程序类是我这样做的方式。但这并没有改变它尴尬和违反直觉的事实。我的意思是如果流是要走的路,会有一些优雅的方法来进行输出流/输入流转换,而不是各种黑客。甚至 Apache IOUtils 也只实现了从 InputStream 到 OutputStream 的复制,而不是相反。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-17
    • 2018-04-07
    • 2018-10-30
    • 1970-01-01
    • 1970-01-01
    • 2019-02-21
    相关资源
    最近更新 更多