Stream, FileStream și MemoryStream în C# (.NET)

.NET BCL și CLI-ul dotnet .NET Framework 1.0

Stream este baza pentru citirea și scrierea de octeți; FileStream lucrează cu fișiere, MemoryStream cu un buffer din memorie.

Sintaxă C#
using var fs = new FileStream(cale, FileMode.Create);   fs.Write(octeti);   ms.Position = 0;   sursa.CopyTo(destinatie)

Ce face Stream, FileStream și MemoryStream

System.IO.Stream este clasa abstractă pentru o secvență de octeți: Read, Write, Seek, Position, Length, CopyTo și variantele Async. Aceeași metodă poate primi un fișier, o zonă de memorie sau o conexiune de rețea, pentru că toate sunt Stream.

FileStream deschide un fișier cu un FileMode (Create, Open, Append, OpenOrCreate) și un FileAccess. File.OpenRead și File.Create sunt prescurtări. MemoryStream ține datele în memorie; după scriere, poziția este la sfârșit, deci înainte de citire o readuci la 0.

Read poate întoarce mai puțini octeți decât ai cerut; valoarea returnată spune câți au fost citiți, iar 0 înseamnă sfârșitul. Din .NET 7, ReadExactly citește exact numărul cerut sau aruncă excepție.

Exemple

Exemplul 1: Text în MemoryStream

În UTF-8, litera ș ocupă doi octeți, deci 12 caractere dau 13 octeți.

using System.Text;

byte[] date = Encoding.UTF8.GetBytes("Salut, Iași!");
Console.WriteLine(date.Length);

using var ms = new MemoryStream();
ms.Write(date);
Console.WriteLine(ms.Position);

ms.Position = 0;
using var cititor = new StreamReader(ms);
Console.WriteLine(cititor.ReadToEnd());

Rezultat

13
13
Salut, Iași!

Exemplul 2: Octeți într-un fișier cu FileStream

using (var fs = new FileStream("date.bin", FileMode.Create, FileAccess.Write))
{
    fs.Write([1, 2, 3, 4, 5, 6]);
}

using (var fs = File.OpenRead("date.bin"))
{
    Console.WriteLine(fs.Length);

    byte[] buffer = new byte[4];
    int citit = fs.Read(buffer, 0, buffer.Length);
    Console.WriteLine($"{citit} octeți: {string.Join(" ", buffer)}");

    fs.Seek(-1, SeekOrigin.End);
    Console.WriteLine(fs.ReadByte());
}

Rezultat

6
4 octeți: 1 2 3 4
6

Greșeli frecvente

  • Citirea dintr-un MemoryStream imediat după scriere întoarce nimic, pentru că poziția este la sfârșit. Setează Position = 0.
  • Ignorarea valorii returnate de Read: bufferul poate fi umplut doar parțial.
  • ms.GetBuffer() întoarce tot bufferul intern, inclusiv octeți nefolosiți de la final; pentru datele scrise folosește ToArray().

Comenzi înrudite

  • StreamReader și StreamWriter: Citesc și scriu text dintr-un fișier sau stream, linie cu linie, fără să încarce tot fișierul în memorie.