内存流和文件流之间的差异

Rag*_*v55 52 c# memorystream filestream

在序列化期间,我们可以使用内存流或文件流.

这两者之间的基本区别是什么?记忆流意味着什么?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;

namespace Serilization
{
    class Program
    {
        static void Main(string[] args)
        {
            MemoryStream aStream = new MemoryStream();
            BinaryFormatter aBinaryFormat = new BinaryFormatter();
            aBinaryFormat.Serialize(aStream, person);
            aStream.Close();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Eni*_*ate 80

Stream是字节的表示.这两个类都派生自Stream类,它是抽象的定义.

顾名思义,FileStream读取和写入文件,而MemoryStream读取和写入内存.因此它与存储流的位置有关.

现在,这取决于您计划如何使用这两者.例如:假设您想要从数据库中读取二进制数据,您将进入MemoryStream.但是,如果要读取系统上的文件,则可以使用FileStream.

MemoryStream的一个快速优势是无需在应用程序中创建临时缓冲区和文件.

  • @Raghav55:一个对象可以缩减为一个字节序列,对吗?在程序逻辑中,该对象具有含义,例如包含名称,地址等信息的Person.这就是对象在程序中的显示方式.当您将其序列化为内存流时,它将减少为无意义的字节流.它只是存储但它对程序逻辑没有实际价值. (18认同)
  • 由于对象已经在内存中,为什么我们要为内容分配一个内存流呢? (10认同)

tom*_*dox 19

这里的其他答案很好,但是我认为深入了解蒸汽的作用可能是有用的。下面的解释中有一些简化,但是希望可以使这个想法得到理解:

什么是流?

流实际上是两个地方之间的数据流,它是管道,而不是该管道的内容。

一个不好的类比开始

想象一下一个海水淡化厂(一种吸收海水,去除盐分并向水网输出清洁饮用水的东西):

海水淡化厂无法一次从整个海洋中去除盐分(我们也不希望它……咸水鱼会住在哪里?),所以我们有:

  • SeaStream那一次入厂吸入水的设定量。
  • SeaStream被连接到DesalinationStream以除去盐
  • 的输出DesalinationStream连接到,DrinkingWaterNetworkStream以将现在的无盐水输出到饮用水源。

好的,那与计算机有什么关系?

一次移动大文件可能会出现问题

在计算中,我们经常想在两个位置之间移动数据,例如,从外部硬盘驱动器移动到数据库中的二进制字段(以使用另一个答案中给出的示例)。我们可以通过将文件中的所有数据从位置A复制到计算机的内存中,再从那里复制到位置B中来做到这一点,但是如果文件很大或源或目标可能不可靠,则可能立即移动整个文件不可行或不明智。

例如,假设我们要将USB记忆棒上的大文件移动到数据库中的字段。我们可以使用“ System.IO.File”对象将整个文件检索到计算机的内存中,然后使用数据库连接将该文件传递到数据库中。

但是,如果文件大于计算机的可用RAM,该怎么办?现在,该文件可能会缓存到硬盘驱动器上,这很慢,甚至可能会减慢计算机的速度。

同样,如果数据源不可靠怎么办,例如,从网络驱动器以缓慢且不稳定的WiFi连接复制文件,该怎么办?一口气复制一个大文件可能会很令人生气,因为您会收到一半的文件,然后连接断开,您必须重新开始,以免再次可能失败。

最好将文件拆分并一次移动一段

因此,与其一次获取整个文件,不如一次检索一个文件,然后一次将每个文件传递到目标位置,这会更好。这就是a的Stream作用,这就是您提到的两种不同类型的流的来源:

  • 我们可以一次使用a FileStream从文件中检索数据
  • 数据库API可能会提供一个MemoryStream端点,我们可以一次写入一个端点。
  • 我们将这两个“管道”连接在一起,以将文件片段从文件流到数据库。

即使文件不是太大,无法保存在RAM中,但如果没有流,我们仍然会执行我们不需要的数字或读/写操作。我们正在执行的阶段是:

  1. 从磁盘检索数据(慢)
  2. 写入计算机内存中的File对象(快一点)
  3. 从计算机内存中的File对象读取(再次更快)
  4. 写入数据库(可能很慢,因为该管道末端可能有旋转的硬盘驱动器)

流使我们可以从概念上省去中间的两个阶段,而不是立即将整个文件拖到计算机内存中,而是取操作的输出来检索数据,然后将其直接传递给操作以将数据传递到数据库中。

流的其他好处

像这样将数据的检索与数据的写入分开,也使我们能够执行检索数据和传递数据之间的动作。例如,我们可以添加一个加密阶段,或者可以将传入的数据写入一种以上类型的输出流(例如,写入FileStream和NetworkStream)。

流还允许我们编写代码,以便在传输部分途中失败的情况下恢复操作。通过保持件数的轨迹我们感动,如果转移失败(例如,如果网络连接中断了),我们可以从我们收到的最后一块点重新开始流(这是offsetBeginRead方法)。


All*_*enG 8

在最简单的形式中,MemoryStream将数据写入内存,而FileStream将数据写入文件.

通常情况下,如果我需要一个流,我会使用MemoryStream,但是我不希望任何东西碰到磁盘,并且在将文件写入磁盘时使用FileStream.


Tud*_*dor 6

当文件流从文件读取时,存储器流可用于读取映射在计算机内部存储器(RAM)中的数据.您基本上是从内存中读取/写入字节流.


小智 5

在这个主题上有痛苦的经历,这就是我发现的。如果需要性能,则应将文件流的内容复制到内存流。我必须处理144个文件的内容,每个文件528 KB,然后将结果呈现给用户。花了大约250秒的时间。(!!!!)。当我仅将每个文件流的内容复制到内存流(CopyTo方法)而完全不做任何更改时,时间减少到大约32秒。请注意,每次将一个流复制到另一个流时,该流都会附加在目标流的末尾,因此您可能需要先“倒带”它,然后再复制到该流。希望能帮助到你。

  • 痛苦的经历?!?当然,处理RAM中的文件比处理磁盘上的文件要快。您期望什么?;-) (9认同)

InG*_*eek 5

就其本身而言stream,一般来说,这意味着当您将内容放入stream(内存)时,它不会将您正在使用的任何数据源(文件,数据库...)的所有内容放入内存。与数组或缓冲区相反,在数组或缓冲区中,您将所有内容都输入到内存中。在 中stream,你会得到一块例如。文件到内存。当到达块的末尾时,stream将下一个块从文件获取到内存。当您只是迭代stream. 这就是为什么它被称为stream.