2013-05-01 57 views
0

所以现在我有一堆模块。这就像一条装配线。有数据流过,每个模块都会处理数据,也可以说下一个模块会消耗前一个模块产生的输出。每个模块都有望成为独立且可重用的模块。这是我想的一个典型场景。使用InputStream/OutputStream处理通过模块的数据流

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

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

回答

1

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

如果将模块分块为通过队列的较小字节数组,则此模式也可以使用字节流,但这并不总是适当的(例如,如果module1读取,module2压缩和module3加密,那么您将数据保存在数据流中可能会更好,除非你有合理的方法来分块数据)。

+0

是的,我的情况非常像module1解析,模块2压缩和模块3加密。分块数据使其适合ConcurrentLinkedQueues或BlockingQueues模式没有意义。这一切都是按顺序发生的。简单,因为它不涉及并发。 – kakacii 2013-05-01 04:32:51

+0

我肯定会听到并了解更多信息,但到目前为止,我认为InputStream/OutputStream设计的很糟糕。这将是处理数据接口的一种很好且清晰的方式。 – kakacii 2013-05-01 04:35:14

+0

您可以使用[IOUtils](http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/IOUtils.html)中的'copy'方法解决此问题,例如[将inputstream复制到outputstream](http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/IOUtils.html#copy%28java.io.InputStream,%20java.io。 OutputStream%29) – 2013-05-01 04:51:18

1

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

另外,你可以实现一些重量更重的消息排队和传递框架如ZeroMQ
--ap

+0

把OutputStream放到InputStream转换中,因为我正在做一个工具类。但它并没有改变这个事实,它是尴尬的,反直觉的。我所说的是,如果stream是要走的路,那么将会有一些优雅的方法来执行OutputStream/InputStream转换,而不是各种黑客。即使是Apache IOUtils也只能实现从InputStream到OutputStream的复制,而不是其他方式。 – kakacii 2013-05-01 04:30:48