我仍然不清楚.NET中的Streams概念
FileStream例如:
using (FileStream fs = File.Open(C:\temp\Test.txt, FileMode.Open, FileAccess.Write, FileShare.None))
上面的代码为我提供了一个FileStrem对象。如果我的理解是正确的,我得到的FileStream对象是文件的字节表示 C:\ TEMP \ Test.txt的
我的问题:是否存在对文件C:\ temp \ Test.txt。
的物理引用FileStream是否只是底层文件的字节表示的抽象。如果是,那么我可以传递这个FileStream对象来说出驻留在其他一些Windows机器上的Web服务。
何时适合使用流。考虑一种情况,我需要从某个远程目录中读取文件并将其SFTP到某个位置。在这里创建一个FIleStream是否有意义?
答案 0 :(得分:2)
Stream
类型基本上是指I / O操作的包装器。这就是它的目的。有时会出现一些花哨的缓存,而MemoryStream
之类的东西肯定不会与任何外部对象交谈,但实质上,理论上就是流是你的流与这些对象交谈。
Stream
的.NET Framework类型的MSDN has a list,这有点太长了,不包括在这里,但你会注意到,对于大多数人来说,目标是从外部源读取或写入,或者在执行这些操作时实时处理其他流。
重要的是要记住,不,流是而不是只是一个字节数组。碰巧字节数组只是一种从流中读取数据的好方法。网络流就是一个很好的例子。如果没有通过任何方式启用缓存,您就无法通过人工方式在流中向后或向前移动 - 您可以阅读数据,而这就是它。
文件流可以让你跳转,因为磁盘位于你身下以做这种事情,但由于网卡不能自己进行缓存,网络无法进行。
因此,不,您不能将流直接传递给Web服务。从本质上讲,在大多数情况下,流只是某些I / O操作的指针(实际上是驱动程序)的包装器。如果系统甚至支持它,它没有通过任何简单的方法,只发送流就像通过电子邮件通知某人链接到C:\驱动器上的文件。
但是,您可以做的是将数据从一个流复制到另一个流。例如,您可以将数据从FileStream
复制到NetworkStream
,从而允许您将文件传输到Web服务。系统将通过数据缓冲数据,基本上从一个流中读取并直接写入另一个流。
为了更好地理解这个实时数据的概念,请看一个例子。想象一下,你正在从磁盘上读取。这需要一些关于硬盘如何工作不可接受或准确的跳跃,但为了示例,它很简单:从文件的开头开始,读取200个字节。硬盘驱动器读取这200个字节,然后停止。然后你要求另外100个字节。磁盘旋转,然后停止。最值得注意的是,磁盘没有读取所有文件,然后将其传递给您。如果它这样做,那么是的,一个字节数组将是一个更好的消耗它的工具。
这里的真正目标是记忆中的内容。使用流,您可以在内存中处理巨大的数量的数据,而无需将所有数据直接提取到内存中。你可以逐块读取它。
我不知道你对LINQ或IEnumerable
一般有多熟悉,但这里的理论是相同的 - 在LINQ中,直到你调用一些ToArray()
或{{ 1}},您的可枚举未经处理。它与延迟执行一起,等待您使用它。在大多数情况下,这也是流的工作原理。
答案 1 :(得分:1)
FileStream是否只是底层文件的字节表示的抽象
不,不是,它是 基础文件的字节表示的读者或作者 的抽象。
Stream
提供了一个接口,允许您在不知道源是什么的情况下读取字节或将字节写入源。您可能正在读取文件或从TCP / IP连接读取,如果使用Stream
操作代码,则代码可以处理0次修改。
您无法将此传递给另一台计算机上的Web服务,因为Stream只是一个读取器,而不是文件本身,因此不会传输文件中的实际信息。
使用流的时间是
byte[]
中同时将整个对象保存在内存中,只需要通过.Read(
和{.Write(
一次访问部分内容{1}}调用将数据加载或存储到更小,更易于管理的byte[]
。在您的SFTP服务器方案中,您属于第二类。在开始将文件写入磁盘之前,您不需要等到整个文件作为byte[]
加载到内存中,您可以从SFTP一次获得一小块数据。 s NetworkStream
并将其写入磁盘FileStream
。实际上,流已经为您提供了一种方法,可以使用方法Stream.CopyTo(Stream destination)
为您执行此过程。