我理解流是字节序列的表示。每个流都提供了将字节读写到其给定的后备存储的方法。但溪流的意义何在?为什么后台存储本身不是我们交互的对象?

不知什么原因,我就是不喜欢这个概念。我读了很多文章,但我觉得我需要一个类比。


当前回答

关键是你不应该知道后台存储是什么——它只是一个抽象。实际上,甚至可能没有备份存储——您可能正在从网络中读取数据,而数据根本就没有“存储”。

如果你写的代码能够在文件系统、内存、网络或任何支持流思想的东西上工作,那么你的代码就会更加灵活。

此外,流通常是链接在一起的——你可以有一个流来压缩放入其中的任何内容,将压缩的表单写入另一个流,或者加密数据,等等。在另一端是反向链,解密,解压缩等等。

其他回答

为了增加回声室,流是一个抽象,所以您不关心底层存储。当您考虑有和没有流的场景时,这是最有意义的。

文件在很大程度上是无趣的,因为除了我熟悉的非基于流的方法之外,流并没有做太多事情。让我们从网络文件开始。

如果我想从互联网上下载一个文件,我必须打开一个TCP套接字,建立一个连接,并接收字节,直到没有更多的字节。我必须管理一个缓冲区,知道预期文件的大小,并编写代码来检测连接何时断开并适当地处理这个问题。

假设我有某种TcpDataStream对象。我用适当的连接信息创建它,然后从流中读取字节,直到它说没有任何字节。流处理缓冲区管理、数据结束条件和连接管理。

通过这种方式,流使I/O更容易。当然,您可以编写一个TcpFileDownloader类来完成流所做的工作,但是这样您就有了一个特定于TCP的类。大多数流接口只提供Read()和Write()方法,任何更复杂的概念都由内部实现处理。因此,您可以使用相同的基本代码来读写内存、磁盘文件、套接字和许多其他数据存储。

流是字节序列的抽象。其思想是,您不需要知道字节来自何处,只需以标准化的方式读取它们。

例如,如果你通过流处理数据,那么数据来自文件、网络连接、字符串、数据库中的blob等等,对你的代码来说都无关紧要。

与备份存储本身交互本身并没有什么问题,除了它将您绑定到备份存储实现。

我使用的可视化是传送带,不是在真实的工厂里,因为我对此一无所知,而是在卡通工厂里,物品沿着线移动,被盖章、装箱、计数和检查,由一系列愚蠢的设备完成。

你有做一件事的简单组件,例如一个把樱桃放在蛋糕上的设备。这个设备有一个无樱桃蛋糕的输入流,和一个有樱桃蛋糕的输出流。用这种方式组织处理有三个优点值得一提。

首先,它简化了组件本身:如果你想把巧克力糖衣放在蛋糕上,你不需要一个复杂的设备,知道蛋糕的一切,你可以创造一个愚蠢的设备,把巧克力糖衣粘在任何东西上(在漫画中,这甚至不知道下一个东西不是蛋糕,而是怀尔E.大狼)。

其次,你可以通过将这些设备按不同的顺序排列来创造不同的产品:也许你想让你的蛋糕在樱桃上放糖衣,而不是樱桃在糖衣上,你可以简单地通过在生产线上交换设备来做到这一点。

Thirdly, the devices don't need to manage inventory, boxing, or unboxing. The most efficient way of aggregating and packaging things is changeable: maybe today you're putting your cakes into boxes of 48 and sending them out by the truckload, but tomorrow you want to send out boxes of six in response to custom orders. This kind of change can be accommodated by replacing or reconfiguring the machines at the start and end of the production line; the cherry machine in the middle of the line doesn't have to be changed to process a different number of items at a time, it always works with one item at a time and it doesn't have to know how its input or output is being grouped.

流是一种抽象,它提供了一组用于与数据交互的标准方法和属性。通过从实际的存储介质中抽象出来,可以编写代码而不完全依赖于该介质是什么,甚至不依赖于该介质的实现。

一个很好的类比可能是考虑一个袋子。你不在乎一个包是什么做的,也不在乎当你把东西放进去的时候它能做什么,只要这个包能发挥它的功能,你就能把东西拿出来。流为存储介质定义了袋的概念,就像袋的概念为袋的不同实例(如垃圾袋、手提包、背包等)定义的那样——交互规则。

关键是你不应该知道后台存储是什么——它只是一个抽象。实际上,甚至可能没有备份存储——您可能正在从网络中读取数据,而数据根本就没有“存储”。

如果你写的代码能够在文件系统、内存、网络或任何支持流思想的东西上工作,那么你的代码就会更加灵活。

此外,流通常是链接在一起的——你可以有一个流来压缩放入其中的任何内容,将压缩的表单写入另一个流,或者加密数据,等等。在另一端是反向链,解密,解压缩等等。