关于c#:内存流和文件流之间的区别

difference between memory stream and filestream

在序列化过程中,我们可以使用内存流或文件流。

这两者的基本区别是什么?记忆流是什么意思?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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();
        }
    }
}

流是字节的表示。这两个类都来自定义为抽象的流类。

顾名思义,文件流读写文件,而memoryStream读写内存。所以它与流的存储位置有关。

现在,这取决于你打算如何使用这两种方法。例如:假设您想从数据库中读取二进制数据,那么您将进入内存流。但是,如果您想要读取系统上的文件,您将进入一个文件流。

memoryStream的一个快速优势是不需要在应用程序中创建临时缓冲区和文件。


这里的其他答案都很好,但我认为,从一个非常高的层次来看蒸汽服务的目的可能是有用的。下面的解释中有一些简单化的内容,但希望这能让我们理解:好的。什么是小溪?

流实际上是两个地方之间的数据流,它是管道,而不是管道的内容。好的。一个糟糕的类比开始

设想一个海水淡化厂(它可以吸收海水,去除盐分,并将干净的饮用水输出到供水网络中):好的。

海水淡化厂不能一次将海水中的盐全部除去(我们也不希望它……海水鱼会生活在哪里?)相反,我们有:好的。

  • 一种一次将一定量的水吸入植物体内的SeaStream
  • SeaStreamDesalinationStream相连,以除去盐。
  • DesalinationStream的输出与DrinkingWaterNetworkStream相连,将现在的无盐水输出到饮用水供应系统。

好吧,那这跟电脑有什么关系?同时移动大文件可能有问题

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

例如,假设我们要将U盘上的一个大文件移动到数据库中的一个字段。我们可以使用"system.io.file"对象将整个文件检索到计算机内存中,然后使用数据库连接将该文件传递到数据库。好的。

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

同样,如果数据源不可靠,例如从具有慢速和不稳定WiFi连接的网络驱动器复制文件,该怎么办?一次复制一个大文件会让人恼火,因为你得到了文件的一半,然后连接断开,你必须重新开始,只会让它再次失败。好的。最好是分割文件,一次移动一个文件

因此,与其一次获取整个文件,不如一次检索一个文件,并将每个文件一次传递到目的地。这就是Stream所做的,这就是您提到的两种不同类型的流的来源:好的。

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

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

  • 从磁盘检索数据(慢)
  • 写入计算机内存中的文件对象(稍快一点)
  • 从计算机内存中的文件对象读取(再次加快)
  • 写入数据库(可能很慢,因为管道末端可能有旋转的磁盘驱动器)
  • 流允许我们在概念上去掉中间的两个阶段,而不是将整个文件立即拖到计算机内存中,而是获取操作的输出以检索数据,并将其直接传输到操作以将数据传递到数据库。好的。流的其他好处

    将数据的检索与数据的写入分开,这样还允许我们在检索数据和传递数据之间执行操作。例如,我们可以添加一个加密阶段,或者将传入数据写入多个类型的输出流(例如,到一个文件流和一个网络流)。好的。

    流还允许我们编写代码,以便在传输部分失败时恢复操作。如果传输失败(例如网络连接断开),通过跟踪我们移动的工件数量,我们可以从接收到最后一个工件的点(这是BeginRead方法中的offset重新启动流。好的。好啊。


    以最简单的形式,memoryStream将数据写入内存,而filestream将数据写入文件。

    通常,如果需要流,我会使用memoryStream,但我不希望任何东西击中磁盘,并且在将文件写入磁盘时使用file stream。


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


    在这个问题上有一段痛苦的经历,这就是我发现的。如果需要性能,则应将文件流的内容复制到memorystream。我必须处理144个文件的内容,每个文件528字节,并向用户展示结果。大约花了250秒。(!!!!!!)当我只是将每个文件流的内容复制到一个memorystream(copyto方法)中而不更改任何内容时,时间下降到大约32秒。请注意,每次将一个流复制到另一个流时,该流都附加在目标流的末尾,因此在复制到目标流之前,可能需要"倒带"它。希望有帮助。


    内存流通过内存缓冲区处理数据。文件流处理磁盘上的文件。


    在我看来,在内存中序列化对象几乎没有任何用处。如果要将对象保存到磁盘上,则需要对其进行序列化。通常,从对象(在内存中)到磁盘进行序列化,而从保存的序列化对象(在磁盘上)到对象(在内存中)进行反序列化。

    因此,大多数情况下,您希望序列化到磁盘,因此使用一个文件流进行序列化。