Rob*_*ers 178 .net java language-agnostic iostream stream
我知道流是字节序列的表示.每个流提供了读取和写入其给定后备存储的字节的方法.但是流的重点是什么?为什么支持商店本身不与我们互动?
无论出于何种原因,这个概念都不是为了点击我.我读了很多文章,但我想我需要一个比喻或类似的东西.
Hos*_*Aly 226
选择"流"这个词是因为它代表(在现实生活中)与我们在使用它时想要表达的非常相似的含义.
让我们稍微忘掉后备商店,开始考虑对水流的类比.您可以获得连续的数据流,就像水在河流中不断流动一样.您不一定知道数据的来源,通常您不需要; 无论是从文件,套接字还是任何其他来源,它都不应该(不应该)真正重要.这非常类似于接收水流,因此您无需知道它来自何处; 无论是从湖泊,喷泉还是其他任何来源,它都不(不应该)真正重要.
也就是说,一旦你开始认为你只关心获得你需要的数据,无论它来自哪里,其他人谈论的抽象变得更加清晰.你开始认为你可以包装流,你的方法仍然可以完美地工作.例如,您可以这样做:
int ReadInt(StreamReader reader) { return Int32.Parse(reader.ReadLine()); }
// in another method:
Stream fileStream = new FileStream("My Data.dat");
Stream zipStream = new ZipDecompressorStream(fileStream);
Stream decryptedStream = new DecryptionStream(zipStream);
StreamReader reader = new StreamReader(decryptedStream);
int x = ReadInt(reader);
Run Code Online (Sandbox Code Playgroud)
如您所见,在不改变处理逻辑的情况下更改输入源变得非常容易.例如,要从网络套接字而不是文件中读取数据:
Stream stream = new NetworkStream(mySocket);
StreamReader reader = new StreamReader(stream);
int x = ReadInt(reader);
Run Code Online (Sandbox Code Playgroud)
尽可能简单.美丽还在继续,因为您可以使用任何类型的输入源,只要您可以为它构建流"包装器".你甚至可以这样做:
public class RandomNumbersStreamReader : StreamReader {
private Random random = new Random();
public String ReadLine() { return random.Next().ToString(); }
}
// and to call it:
int x = ReadInt(new RandomNumbersStreamReader());
Run Code Online (Sandbox Code Playgroud)
看到?只要您的方法不关心输入源是什么,您就可以通过各种方式自定义源.抽象允许您以非常优雅的方式将输入与处理逻辑分离.
请注意,我们自己创建的流没有后备存储,但它仍然完美地满足我们的目的.
因此,总而言之,流只是输入源,隐藏(抽象)另一个源.只要你不打破抽象,你的代码就会非常灵活.
Jon*_*eet 36
关键是你不应该知道后备存储是什么 - 它是对它的抽象.事实上,甚至可能不会是一个后备存储-你可以从网络上阅读,而数据永远不会"存储"在所有.
如果您可以编写的代码无论您是在与文件系统,内存,网络还是其他任何支持流概念的内容进行通信,那么您的代码就会更加灵活.
此外,流通常链接在一起 - 你可以有一个流压缩放入其中的任何内容,将压缩的表单写入另一个流,或者加密数据的流,等等.另一端是反向的链,解密,解压缩等等.
要添加到echo室,流是一个抽象,因此您不关心底层存储.当您考虑使用和不使用流的方案时,它最有意义.
文件在大多数情况下都是无趣的,因为流不会超出我熟悉的基于非流的方法.让我们从互联网文件开始吧.
如果我想从互联网上下载文件,我必须打开TCP套接字,建立连接,并接收字节,直到没有更多的字节.我必须管理一个缓冲区,知道预期文件的大小,并编写代码来检测连接何时被删除并适当地处理它.
假设我有某种TcpDataStream对象.我使用适当的连接信息创建它,然后从流中读取字节,直到它说没有更多的字节.该流处理缓冲区管理,数据结束条件和连接管理.
通过这种方式,流使I/O更容易.你当然可以编写一个TcpFileDownloader类来完成流的工作,但是你有一个特定于TCP的类.大多数流接口只提供Read()和Write()方法,而任何更复杂的概念都由内部实现处理.因此,您可以使用相同的基本代码来读取或写入内存,磁盘文件,套接字和许多其他数据存储.
小智 5
我使用的可视化是传送带,不是在真正的工厂中,因为我对此一无所知,而是在卡通工厂中,物品沿线移动并被盖章和装箱,并由一系列愚蠢的设备进行计数和检查。
你有一个简单的组件可以做一件事,例如一个把樱桃放在蛋糕上的设备。该设备具有无樱桃蛋糕的输入流和带有樱桃的蛋糕的输出流。以这种方式构建您的处理有三个值得一提的优点。
首先,它简化了组件本身:如果你想把巧克力糖霜放在蛋糕上,你不需要一个了解蛋糕一切的复杂设备,你可以创建一个愚蠢的设备,将巧克力糖霜粘在任何喂入的东西上(在卡通,这甚至不知道下一个项目不是蛋糕,而是 Wile E. Coyote)。
其次,您可以通过将设备放入不同的序列来创建不同的产品:也许您希望蛋糕上有樱桃糖霜而不是樱桃糖霜,您只需在生产线上交换设备即可.
第三,设备不需要管理库存、装箱或拆箱。最有效的聚合和包装方式是多变的:也许今天您将蛋糕放入 48 个一盒并用卡车装运出去,但明天您想发送 6 个一盒的蛋糕以响应定制订单。这种变化可以通过更换或重新配置生产线起点和终点的机器来适应;不必更改生产线中间的樱桃机器以一次处理不同数量的项目,它始终一次处理一个项目,并且不必知道其输入或输出如何被分组。
当我第一次听说流媒体时,是在使用网络摄像头进行直播的背景下。因此,一台主机正在广播视频内容,而另一台主机正在接收视频内容。所以这是直播吗?嗯......是的......但直播是一个具体的概念,我认为这个问题指的是Streaming的抽象概念。请参阅https://en.wikipedia.org/wiki/Live_streaming
所以让我们继续。
视频并不是唯一可以流式传输的资源。音频也可以流式传输。所以我们现在谈论的是流媒体。请参阅https://en.wikipedia.org/wiki/Streaming_media。音频可以通过多种方式从源传送到目标。因此,让我们比较一些数据传递方法。
经典文件下载 经典文件下载不是实时发生的。在使用文件之前,您必须等到下载完成。
渐进式下载 渐进式下载块将数据从流媒体文件下载到临时缓冲区。该缓冲区中的数据是可用的:缓冲区中的音视频数据是可播放的。因此,用户可以在下载时观看/收听流媒体文件。快进和倒带是可能的,当然有缓冲区。无论如何,渐进式下载不是直播。
流式传输 实时发生,并分块数据。流媒体是在直播中实现的。收听广播的客户端不能快进或倒带。在视频流中,数据在播放后被丢弃。
流服务器与其客户端保持 2 路连接,而 Web 服务器在服务器响应后关闭连接。
音频和视频并不是唯一可以流式传输的内容。我们来看看 PHP 手册中流的概念。
流是一个资源对象,它表现出可流式传输的行为。也就是说,它可以以线性方式读取或写入,并且可能能够 fseek() 到流中的任意位置。链接:https : //www.php.net/manual/en/intro.stream.php
在 PHP 中,资源是对外部源(如文件、数据库连接)的引用。因此,换句话说,流是可以读取或写入的源。因此,如果您使用过fopen()
,那么您已经使用过流。
受流处理的文本文件的示例:
// Let's say that cheese.txt is a file that contains this content:
// I like cheese, a lot! My favorite cheese brand is Leerdammer.
$fp = fopen('cheese.txt', 'r');
$str8 = fread($fp, 8); // read first 8 characters from stream.
fseek($fp, 21); // set position indicator from stream at the 21th position (0 = first position)
$str30 = fread($fp, 30); // read 30 characters from stream
echo $str8; // Output: I like c
echo $str30; // Output: My favorite cheese brand is L
Run Code Online (Sandbox Code Playgroud)
Zip 文件也可以流式传输。最重要的是,流媒体不仅限于文件。HTTP、FTP、SSH 连接和输入/输出也可以流式传输。
维基百科对流媒体的概念有什么看法?
在计算机科学中,流是随时间可用的一系列数据元素。流可以被认为是传送带上一次处理一个而不是大批量的项目。
请参阅:https : //en.wikipedia.org/wiki/Stream_%28computing%29。
维基百科链接到这个:https : //srfi.schemers.org/srfi-41/srfi-41.html ,作者对流有以下说法:
流,有时称为惰性列表,是一种顺序数据结构,包含仅按需计算的元素。一个流要么是空的,要么是在它的 cdr 中与一个流成对的。由于流的元素仅在访问时计算,因此流可以是无限的。
所以Stream实际上是一种数据结构。
我的结论是:流是一个源,可以包含可以按顺序读取或写入的数据。流不会一次读取源包含的所有内容,而是按顺序读取/写入。
有用的链接:
归档时间: |
|
查看次数: |
21047 次 |
最近记录: |