流及其在.Net中的用途

  • 本文关键字:Net .net stream
  • 更新时间 :
  • 英文 :


我仍然不清楚.NET 中Streams的概念

FileStream,例如:

using (FileStream fs = File.Open(C:tempTest.txt, FileMode.Open, FileAccess.Write, FileShare.None)) 

上面的代码为我获取了一个FileStrem对象。如果我的理解是正确的,我得到的FileStream对象是文件的字节表示C: \temp\Test.txt

我的问题是:是否有对文件C:\temp\Test.txt的物理引用。

FileStream只是底层文件的字节表示的抽象。如果是,那么我可以传递这个FileStream对象来表示驻留在其他windows机器上的Web服务吗。

还有什么时候使用流是合适的。考虑一个场景,我需要从某个远程目录读取一个文件,并将其SFTP到某个位置。在这里创建FIleStream有意义吗?

Stream类型从根本上说是I/O操作的包装器。这就是它的目的。有时会有一些奇特的缓存,肯定有MemoryStream这样的东西不与任何外部对象通信,但从本质上讲,理论是流就是你与这些对象通信的方式。

MSDN有一个继承自Stream的.NET Framework类型列表,这有点太长了,不需要在这里列出,但您会注意到,对于大多数类型,目标要么是从外部源读取或写入,要么是在执行这些操作时实时处理其他流。

重要的是要记住,不,流是而不是,只是一个字节数组。字节数组恰好是从流中读取数据的一种非常好的方法。网络流就是一个很好的例子。如果不通过任何方式打开缓存,你就没有办法在流中人为地前后移动——你读取数据,就这样

文件流可以让你跳来跳去,因为磁盘就在你下面做这种事情,但由于NIC不单独进行缓存,网络就不能。

因此,不,您不能将流直接传递给Web服务。从本质上讲,在大多数情况下,流只是指向某个I/O操作的指针(实际上是一个驱动程序)的包装器。如果系统甚至支持它,而这并不是通过任何简单的方式实现的,那么只发送流就像通过电子邮件向某人发送C:\驱动器上文件的链接一样。

然而,您可以做的是将数据从一个流复制到另一个流。例如,您可以将数据从FileStream复制到NetworkStream,从而允许您将文件传输到web服务。数据将在传输过程中由系统缓冲,基本上从一个流中读取并直接写入另一个流。

为了更好地理解实时数据的概念,请看一个示例。想象一下你正在读磁盘。这对硬盘驱动器的工作方式进行了一些不可接受或不准确的飞跃,但就示例而言,它很简单:从文件的开头开始,读取200字节。硬盘驱动器读取这200个字节,然后停止。然后,您要求再输入100个字节。磁盘旋转,然后停止。这里最值得注意的是,磁盘不会读取所有文件,然后将其传递给您。如果它做到了,那么是的,字节数组将是一个更好的消费工具

这里真正的目标是记忆中的东西。使用流,您可以在内存中处理大量数据,实际上是无限的,而不必首先将所有数据直接拉入内存。你可以一块一块地读。

我不知道你对LINQ或IEnumerable有多熟悉,但这里的理论是一样的——在LINQ中,除非你调用一些ToArray()ToList(),否则你的枚举数不会被处理。它具有延迟执行功能,等待您使用它。在大多数情况下,流也是这样工作的。

FileStream只是底层文件的字节表示的抽象吗

不,它不是,它是底层文件字节表示的读取器或写入器的抽象。

Stream提供了一个接口,允许您在不知道源是什么的情况下读取源中的字节或向该源写入字节。您可以读取文件或从TCP/IP连接读取,如果您的代码使用Stream操作,则您的代码可以在0修改的情况下处理这两者。

您无法将其传递给另一台计算机上的Web服务,因为Stream只是一个读取器,而不是文件本身,因此不会传输文件中的实际信息。

  1. 您需要对数据源或目标进行抽象,这样就可以使用多个源,而无需为源类型编写单独的函数
  2. 您使用的是大型对象,不需要在byte[]中一次将整个对象保存在内存中,只需要通过.Read(.Write(调用一次访问部分,将数据加载或存储到更小、更易于管理的byte[] s中

在SFTP服务器的场景中,您属于第二类。在开始将文件写入磁盘之前,不需要等到整个文件作为byte[]加载到内存中,您可以一次从SFTP的NetworkStream获取小块数据,并将其写入磁盘FileStream。事实上,stream已经为您提供了一种方法,用方法Stream.CopyTo(Stream destination)为您完成这个精确的过程。

相关内容

  • 没有找到相关文章

最新更新