c# 內存流和文件流之間的差異




c# stream to file (6)

在序列化期間,我們可以使用內存流或文件流。

這兩者之間的基本區別是什麼? 記憶流意味著什麼?

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();
        }
    }
}

Answer #1

在我看來,在內存中序列化對象幾乎沒有任何用處。 如果要將對象保存在磁盤上,則需要序列化對象。 通常,序列化是從對象(在內存中)到磁盤完成的,而反序列化是從保存的序列化對象(在磁盤上)到對象(在內存中)完成的。

因此,大多數情況下,您希望序列化到磁盤,因此您使用Filestream進行序列化。


Answer #2

內存流通過內存緩衝區處理數據。 文件流處理磁盤上的文件。


Answer #3

這裡的其他答案都很棒,但我認為一個真正高水平看一下蒸汽用途的目的可能是有用的。 在下面的解釋中有一些簡化,但希望這可以解決這個問題:

什麼是流?

流實際上是兩個地方之間的數據流,它是管道而不是管道的內容。

一個糟糕的比喻開始

想像一下一個海水淡化廠(需要海水,去除鹽並向水網輸出乾淨的飲用水):

海水淡化廠不能同時從所有海洋中除去鹽(我們也不希望它......鹹水魚會在哪里居住?),所以我們有:

  • SeaStream吸入一定量的水進入工廠。
  • SeaStream連接到DesalinationStream以移除鹽
  • DesalinationStream的輸出連接到DrinkingWaterNetworkStream ,將現在無鹽的水輸出到飲用水供應。

好的,那與計算機有什麼關係呢?

一次移動大文件可能會有問題

經常在計算中我們想要在兩個位置之間移動數據,例如從外部硬盤驅動器到數據庫中的二進製字段(使用另一個答案中給出的示例)。 我們可以通過將文件中的所有數據從位置A複製到計算機的內存中並從那裡複製到位置B,但是如果文件很大或者源或目標可能不可靠,那麼立即移動整個文件可能無論是不可行還是不明智。

例如,假設我們要將USB記憶棒上的大文件移動到數據庫中的字段。 我們可以使用'System.IO.File'對象將整個文件檢索到計算機的內存中,然後使用數據庫連接將該文件傳遞到數據庫中。

但是,這可能存在問題,如果文件大於計算機的可用RAM會怎麼樣? 現在該文件可能會緩存到硬盤驅動器上,這很慢,甚至可能會使計算機速度降低。

同樣,如果數據源不可靠,例如從具有緩慢和片狀WiFi連接的網絡驅動器複製文件,該怎麼辦? 試圖一次性複制一個大文件可能會令人憤怒,因為你獲得了一半的文件,然後連接斷了,你必須重新開始,只是因為它可能再次失敗。

最好將文件拆分並一次移動一塊

因此,不是一次獲取整個文件,最好一次檢索一個文件並一次將每個文件傳遞到目標文件。 這就是Stream功能,這就是您提到的兩種不同類型的流的來源:

  • 我們可以使用FileStream從一個文件中檢索數據
  • 並且數據庫API可以提供我們可以一次寫入一個片段的MemoryStream端點。
  • 我們將這兩個“管道”連接在一起,將文件從文件傳輸到數據庫。

即使文件不是太大而無法保存在RAM中,如果沒有流,我們仍然在做一些我們不需要的數字或讀/寫操作。 我們正在進行的階段是:

  1. 從磁盤檢索數據(慢)
  2. 寫入計算機內存中的File對象(快一點)
  3. 從計算機內存中的File對象讀取(再次更快)
  4. 寫入數據庫(可能很慢,因為在該管道末端可能存在旋轉磁盤硬盤驅動器)

Streams允許我們在概念上取消中間兩個階段,而不是立即將整個文件拖入計算機內存,我們採取操作的輸出來檢索數據並直接管道操作以將數據傳遞到數據庫。

流的其他好處

將數據的檢索與這樣的數據寫入分開也允許我們在檢索數據和傳遞數據之間執行操作。 例如,我們可以添加加密階段,或者我們可以將傳入數據寫入多種類型的輸出流(例如,寫入FileStream和NetworkStream)。

Streams還允許我們編寫代碼,如果傳輸失敗,我們可以恢復操作。 通過跟踪我們移動的塊數,如果傳輸失敗(例如,如果網絡連接斷開),我們可以從我們收到最後一塊的點重新啟動Stream(這是BeginRead方法中的offset )。


Answer #4

Stream是字節的表示。 這兩個類都派生自Stream類,它是抽象的定義。

顧名思義,FileStream讀取和寫入文件,而MemoryStream讀取和寫入內存。 因此它與存儲流的位置有關。

現在,這取決於您計劃如何使用這兩者。 例如:假設您想要從數據庫中讀取二進制數據,您將進入MemoryStream。 但是,如果要讀取系統上的文件,則可以使用FileStream。

MemoryStream的一個快速優勢是無需在應用程序中創建臨時緩衝區和文件。


Answer #5

在最簡單的形式中,MemoryStream將數據寫入內存,而FileStream將數據寫入文件。

通常情況下,如果我需要一個流,我會使用MemoryStream,但是我不希望任何東西碰到磁盤,並且在將文件寫入磁盤時使用FileStream。


Answer #6

當文件流從文件讀取時,存儲器流可用於讀取映射在計算機內部存儲器(RAM)中的數據。 您基本上是從內存中讀取/寫入字節流。





memorystream