2011-04-27 123 views
2

过去几天我一直在阅读Java中的流。在阅读了很多内容之后,我开始明白,“流”这个名字是因为与我们在“现实生活”中使用的词相似而被选中的,例如水。而且没有必要知道数据来自哪里。如果我解释错了,请纠正。关于Java中流的问题

但我不明白这一点。当我在插座上说getOutputStreamgetInputStream时,我得到一个InputStream,我可以链接到任何我喜欢的东西。但是不是InputStream/OutputStream抽象类?我不知道如何正确解释它,但我不明白,只通过调用该方法的套接字连接自动具有字节/字符可以流动的流/通道?什么是实际上是一个InputStream/OutputStream?流是一种抽象真实来源的方式吗?

我想我理解链接他们的各种方式,但我觉得我错过了这个概念的核心。

由于缺乏正确的解释方法,我会删除问题,如果它不好。

谢谢你的时间。

回答

3

InputStream/OutputStream是,很好,抽象。它们为读取/写入字节或字节组提供了一些基本的API,而不会暴露实际的实现。我们以OutputStream为例:

OutputStream通过公共API接收一堆字节。你实际上并不知道(并关心)这些字节后发生了什么:他们是发送。真正的实现可以:将它们附加到文件中,忽略它们(Apache Commons中的NullOutputStream),将它们保存在内存中或...通过套接字发送。

这是当你调用Socket.getOutputStream()会发生什么:你一些实施OutputStream,只是不小心,它是依赖于实现和具体。当你向这个流发送字节时,底层实现将使用TCP/IP或UDP来推送它们。事实上,TCP/IP本身就是一个流协议,尽管它在数据包/帧上运行。

这种情况是类似的InputStream - 你从一些执行从套接字。当你询问流的几个字节时,底层的InputStream实现将询问OS套接字相同的字节量,可能会阻塞。但这是继承的真正乐趣:你不在乎!只要使用这些流你想要的任何方式,链接,缓冲等。

+0

太好了,谢谢。那就是我所追求的,实际上我应该停止关注发生的事情。 – LuckyLuke 2011-04-27 21:45:23

3

当您调用getInputStream时,套接字将返回一些具体子类InputStream的实例。通常你不用担心返回对象的确切类。因为它是一个InputStream,你只需要这样工作。 (子类甚至可能是套接字类的私有嵌套类。)

3

InputStream确实是一个抽象。每次都可以使用流概念的不同实现。但是流的用户不需要知道确切的实现是什么。

Socket的情况下,该实现是SocketInputStream延伸FileInputStream

3

我不认为这是一个坏问题。你说得很对,这些流将数据的来源复杂化,并使其统一起来。因此,您可以编写从文件或套接字读取的代码,并且该代码看起来几乎完全相同。这意味着你通常不得不编写更少的代码。

当您从Socket获得InputStream时,您可以访问到达该套接字的任何数据。从这个流中读取数据时,通常会提供一个字节数组,并要求流为它填充。它将读取尽可能多的数据或填充缓冲区。这取决于你如何处理这个字节数组中的数据。

对于任何类型的Socket IO,虽然已经说过关于Streams的所有内容,但是Java套接字API是相当古老的,并且有一些非常好的替代方案可用于包装它并更易于使用。我强烈建议使用Netty,您可以使用它来忘记流并关注POJO以及如何对它们进行编码和解码。