This article is currently in the process of being translated into Russian (~99% done).
MemoryStream
MemoryStream является одним из основных классов потоков (Stream), который, как вы поймете позже, используется не часто. Он используется для манипуляции данными прямо из оперативной памяти, как и подразумевает его название, а также часто используется для манипуляций с байтами из других мест, таких как файл и сетевое расположение, при этом не блокируя источник данных.
Например, вы можете считать целое содержимое файла в MemoryStream, который сразу же заблокирует и разблокирует файл, а затем начнет обрабатывать байты в MemoryStream. Если вам необходимо часто проходить через байты, это так же гораздо быстрее, чем делать это напрямую в, например, классе FileStream, потому что байты из MemoryStream хранятся в оперативной памяти.
Поэтому часто можно увидеть как объект MemoryStream инициализируется массивом байтов (byte[]), который может быть получен из разных источников. Затем экземпляр класса MemoryStream может быть передан в других механизмах, например в одном из типов StreamReader:
public void UseMemoryStream()
{
byte[] fileContents = File.ReadAllBytes("test.txt");
using(MemoryStream memoryStream = new MemoryStream(fileContents))
{
using(TextReader textReader = new StreamReader(memoryStream))
{
string line;
while((line = textReader.ReadLine()) != null)
Console.WriteLine(line);
}
}
}
В этом примере мы считываем все байты из простого текстового файла. Затем мы создаем MemoryStream с этими байтами, а затем создаем экземпляр StreamReader, который будет читать все строки из MemoryStream. Как показано в этом примере, MemoryStream является хорошим резервным источником для другого класса, который будет выполнять работу, в данном случае StreamReader.
Использование классов StreamReader/StreamWriter - это хороший способ работы с базовым потоком, но если вы настаиваете, вы можете считывать байты непосредственно из MemoryStream и работать с ними. Класс MemoryStream содержит несколько методов для этого, например, метод ReadByte(). Он считывает байт в текущей позиции, возвращает его, а затем продвигает свойство Position, подготавливая MemoryStream к чтению следующего байта. Вот пример:
public void UseMemoryStream()
{
byte[] fileContents = File.ReadAllBytes("test.txt");
using(MemoryStream memoryStream = new MemoryStream(fileContents))
{
int b;
while((b = memoryStream.ReadByte()) >= 0)
Console.WriteLine(Convert.ToChar(b));
}
}
Он будет читать каждый байт, найденный в MemoryStream, и выводить его на консоль. Обратите внимание, что я использую метод Convert.ToChar(), чтобы превратить байт в символ ASCII, поскольку я знаю, что источник - это открытый текст.
Резюме
Класс MemoryStream можно использовать в качестве резервного источника данных, которые вы хотите хранить в памяти. Это делает его отличным временным хранилищем для данных, поступающих из файла или сетевого ресурса, чтобы предотвратить блокировку и т.д., пока вы работаете с данными.