Как использовать BufferedStream и MemoryStream в C#

автор vadim


Поток — это абстракция над последовательностью байтов. Вы можете думать об этом как о непрерывном буфере, который можно читать или записывать. Потоки часто используются в сочетании с буферами для более эффективной загрузки данных в память. Пространство имен System.IO в .NET содержит множество классов, которые работают с потоками, например классы FileStream, MemoryStream, FileInfo и StreamReader/Writer.

По сути, потоки классифицируются как потоки байтов или потоки символов, где потоки байтов имеют дело с данными, представленными в виде байтов, а потоки символов имеют дело с символами. В .NET потоки байтов включают классы Stream, FileStream, MemoryStream и BufferedStream. Потоки символов .NET включают TextReader, TextWriter, StreamReader и StreamWriter.

В этой статье показано использование классов BufferedStream и MemoryStream в C# с соответствующими примерами кода, где это применимо. Для работы с примерами кода, представленными в этой статье, в вашей системе должна быть установлена ​​Visual Studio 2022. Если у вас еще нет копии, вы можете скачать Visual Studio 2022 здесь.

Создайте проект консольного приложения в Visual Studio.

Прежде всего, давайте создадим проект консольного приложения .NET Core в Visual Studio. Предполагая, что Visual Studio 2022 установлена ​​в вашей системе, выполните шаги, описанные ниже, чтобы создать новый проект консольного приложения .NET Core в Visual Studio.

  1. Запустите интегрированную среду разработки Visual Studio.
  2. Нажмите «Создать новый проект».
  3. В окне «Создать новый проект» выберите «Консольное приложение (.NET Core)» из списка отображаемых шаблонов.
  4. Нажмите “Далее.
  5. В следующем окне «Настройка нового проекта» укажите имя и местоположение нового проекта.
  6. Нажмите “Далее.
  7. В следующем окне «Дополнительная информация» выберите «.NET 7.0 (стандартная поддержка)» в качестве версии платформы, которую вы хотите использовать.
  8. Щелкните Создать.

Мы будем использовать этот проект консольного приложения .NET 7 для работы с классами BufferedStream и MemoryStream в последующих разделах этой статьи.

Что такое буфер?

Буфер представляет собой блок байтов в памяти, где вы можете временно хранить временные данные. Буфер помогает свести к минимуму количество вызовов, которые ваше приложение делает для чтения и записи данных из файловой системы и в нее. Буферы полезны, когда вам нужно хранить данные, которые передаются из одной компьютерной системы в другую или из одного компонента программы в другой.

Буферы используются вместе с потоками, чтобы облегчить программам эффективное чтение и запись данных. Буферы временно хранят данные, поэтому вашему приложению не нужно будет повторно считывать данные с диска каждый раз, когда они запрашиваются.

Используйте класс BufferedStream в C#

Класс BufferedStream представляет тип потока, который может буферизовать данные перед их записью в поток. Другими словами, буферизованный поток может считывать или записывать данные в буфер, что позволяет одновременно считывать или записывать большие фрагменты данных для повышения производительности. Вы можете создавать буферизованные потоки из потоков памяти и файловых потоков.

При создании экземпляра класса BufferedStream вы также можете указать размер буфера. Размер буфера по умолчанию составляет 4096 байт. Чтение данных из буферизованного потока включает чтение из буфера при вызове метода Read. Даже если вы вызовете Read несколько раз, данные будут извлечены из потока только один раз.

При записи в буферизованный поток данные записываются в буфер, а затем сбрасываются в поток при вызове метода Flush. Это повышает производительность, избегая доступа к потоку для каждого вызова Write. Когда мы используем буфер, мы не выполняем операции записи или чтения до тех пор, пока не будет запрошено определенное количество операций.

Сохраняя некоторый объем данных в своем внутреннем буфере, BufferedStream может выполнять несколько операций с одним и тем же фрагментом памяти без необходимости снова и снова выделять память. Это экономит время и потребление памяти при многократном создании новых объектов.

Обратите внимание, что вы можете использовать экземпляр BufferedStream либо для чтения данных, либо для записи данных, но вы не можете использовать один и тот же экземпляр для обеих операций. BufferedStream предназначен для предотвращения замедления ввода и вывода, когда нет необходимости в буфере. Буферизованный поток может даже не выделять внутренний буфер, если размер чтения и записи всегда больше, чем размер внутреннего буфера.

В следующем фрагменте кода показано, как вы можете записывать данные в файл с помощью BufferedStream.

 
using (FileStream fileStream = new FileStream("D:\\MyTextFile.txt", FileMode.Create, FileAccess.ReadWrite))
{
      BufferedStream bufferedStream = new BufferedStream(fileStream, 1024);
      byte[] bytes = Encoding.ASCII.GetBytes("This is a sample text.");
      bufferedStream.Write(bytes);
      bufferedStream.Flush();
      bufferedStream.Close();
}

Когда следует использовать BufferedStream? Используйте BufferedStream, если вы хотите добавить поддержку буферизации в существующий поток. Таким образом, если бы исходный поток был сетевым потоком, данные, отправленные в него, были бы кэшированы в небольшом буфере перед записью или извлечением из сетевого потока.

Использование класса MemoryStream в C#

Класс MemoryStream представляет собой облегченный поток, который позволяет выполнять запись или чтение из буфера памяти. Класс MemoryStream поддерживает те же методы и свойства, что и класс Stream. MemoryStream предоставляет простой способ чтения или записи данных непосредственно из памяти без необходимости выделения и освобождения памяти каждый раз, когда вы хотите что-то прочитать или записать. Это делает его быстрее, чем при использовании других методов, требующих перераспределения памяти при каждом использовании.

Поток памяти — это очень быстрый и эффективный поток, поскольку данные находятся в памяти. Однако это также означает, что его можно легко потерять в случае сбоя программы или резкого выключения компьютера.

Класс MemoryStream является частью пространства имен System.IO. Его можно использовать для чтения и записи файлов, сетевых подключений и других устройств, поддерживающих чтение и запись данных. Класс MemoryStream также можно использовать для сериализации объекта в поток байтов для хранения или передачи по сетевому соединению.

В следующем фрагменте кода показано, как вы можете записывать данные в поток памяти на C#.

 
byte[] bytes = System.Text.Encoding.ASCII.GetBytes("This is a sample text.");
using (MemoryStream memoryStream = new MemoryStream(50))
{
     memoryStream.Write(bytes, 0, bytes.Length);
}

Когда следует использовать MemoryStream? Как следует из названия, MemoryStream — это поток только для памяти. Таким образом, его следует использовать только тогда, когда объем данных, которые необходимо кэшировать, достаточно мал, чтобы удобно разместиться в памяти.

Хотя BufferedStream быстрее и эффективнее, MemoryStream хорошо подходит для сценариев, в которых вашему приложению требуется более быстрый доступ к данным. Вы можете использовать асинхронные версии методов чтения и записи классов BufferedStream и MemoryStream для еще большей производительности и масштабируемости.

Related Posts

Оставить комментарий