Разница между потоком памяти и фильтром

Во время сериализации мы можем использовать либо поток памяти, либо поток файлов.

В чем основное отличие этих двух? Что означает поток памяти?

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

Ответ 1

Поток - это представление байтов. Оба эти класса происходят из класса Stream, который по определению является абстрактным.

Как следует из названия, FileStream считывает и записывает в файл, тогда как MemoryStream считывает и записывает в память. Поэтому он относится к тому, где хранится поток.

Теперь это зависит от того, как вы планируете использовать оба из них. Например, предположим, что вы хотите читать двоичные данные из базы данных, вы будете использовать MemoryStream. Однако, если вы хотите прочитать файл в своей системе, вы можете использовать FileStream.

Одним из быстрых преимуществ MemoryStream является то, что нет необходимости создавать временные буферы и файлы в приложении.

Ответ 2

Другие ответы здесь великолепны, но я подумал, что может быть полезен тот, который действительно высоко оценивает, для чего служат пары. В приведенном ниже объяснении происходит некоторое упрощение, но, надеюсь, это поможет понять идею:

Что такое поток?

Поток - это, по сути, поток данных между двумя местами, это скорее канал, а не содержимое этого канала.

Плохая аналогия для начала

Представьте себе опреснительную установку (которая забирает морскую воду, удаляет соль и выводит чистую питьевую воду в водопроводную сеть):

Опреснительная установка не может удалить соль со всего моря за один раз (и при этом мы не хотим, чтобы… где обитала морская рыба?), Поэтому вместо этого мы имеем:

  • SeaStream который всасывает определенное количество воды за раз в растение.
  • Этот SeaStream подключен к DesalinationStream для удаления соли
  • А выход DesalinationStream подключается к DrinkingWaterNetworkStream для вывода теперь бессолевой воды в систему питьевого водоснабжения.

Хорошо, так какое это имеет отношение к компьютерам?

Перемещение больших файлов одновременно может быть проблематичным

Часто в вычислениях мы хотим перемещать данные между двумя местоположениями, например, с внешнего жесткого диска в двоичное поле в базе данных (чтобы использовать пример, приведенный в другом ответе). Мы можем сделать это, скопировав все данные из файла из местоположения A в память компьютера и оттуда в местоположение B, но если файл большого размера или источник или место назначения потенциально ненадежны, то перемещение всего файла за раз может быть невыполнимым или неразумным.

Например, скажем, мы хотим переместить большой файл на USB-накопителе в поле в базе данных. Мы могли бы использовать объект System.IO.File для извлечения всего этого файла в память компьютера, а затем использовать соединение с базой данных для передачи этого файла в базу данных.

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

Аналогично, что, если источник данных ненадежен, например, копирование файла с сетевого диска с медленным и нестабильным WiFi-соединением? Попытка скопировать большой файл за один раз может приводить в бешенство, потому что вы получаете половину файла, а затем соединение обрывается, и вам приходится начинать все сначала, только чтобы он потенциально мог снова потерпеть неудачу.

Может быть лучше разбить файл и переместить его по частям за раз

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

  • Мы можем использовать FileStream для извлечения данных из файла по частям за раз
  • и API базы данных может сделать доступной конечную точку MemoryStream мы можем записать в кусок за раз.
  • Мы соединяем эти два "канала" вместе, чтобы передавать части файла из файла в базу данных.

Даже если файл не был слишком большим для хранения в оперативной памяти, без потоков мы все равно выполняли операции с числами или операции чтения/записи, которые нам не нужны. Этапы, которые мы проводим, были:

  1. Извлечение данных с диска (медленно)
  2. Запись в файл объекта в памяти компьютера (немного быстрее)
  3. Чтение из этого объекта File в памяти компьютера (снова быстрее)
  4. Запись в базу данных (возможно, медленная, так как, возможно, в конце этого канала находится жесткий диск с вращающимся диском)

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

Другие преимущества потоков

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

Потоки также позволяют нам писать код, в котором мы можем возобновить операцию, если передача завершится неудачно. Отслеживая количество фрагментов, которые мы переместили, если передача не удалась (например, если сетевое соединение прерывается), мы можем перезапустить поток с того места, в котором мы получили последний фрагмент (это offset в методе BeginRead).

Ответ 3

В простейшей форме MemoryStream записывает данные в память, а FileStream записывает данные в файл.

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

Ответ 4

Пока поток файлов считывается из файла, поток данных может использоваться для чтения данных, отображаемых во внутренней памяти компьютера (ОЗУ). Вы в основном читаете/записываете потоки байтов из памяти.

Ответ 5

Имея горький опыт в этом вопросе, вот что я узнал. если производительность требуется, вы должны скопировать содержимое фильтра в запоминающий поток. Мне пришлось обработать содержимое 144 файлов по 528 кбайт каждый и представить результат для пользователя. Это заняло 250 секунд. (!!!!). Когда я только что скопировал содержимое каждого файла в memystream (метод CopyTo), ничего не изменив, время снизилось примерно до 32 секунд. Обратите внимание, что каждый раз, когда вы копируете один поток в другой, поток добавляется в конец целевого потока, поэтому вам может потребоваться "перемотать" его перед копированием на него. Надеюсь, поможет.

Ответ 6

Поток памяти обрабатывает данные через буфер памяти. Файловый поток имеет дело с файлами на диске.

Ответ 7

Сериализация объектов в памяти вряд ли будет полезной, на мой взгляд. Вам нужно сериализовать объект, если вы хотите сохранить его на диске. Как правило, сериализация выполняется из объекта (который находится в памяти) на диск, а десериализация выполняется из сохраненного сериализованного объекта (на диске) в объект (в памяти).

Итак, большую часть времени вы хотите сериализовать на диск, таким образом, вы используете Filestream для сериализации.

Ответ 8

Что касается самого stream, в общем, это означает, что когда вы помещаете контент в stream (память), он не помещает все содержимое какого-либо источника данных (file, db...), с которым вы работаете с в память. В отличие, например, от массивов или буферов, где вы все подаете в память. В stream вы получите кусок, например. файл в память. Когда вы достигаете конца фрагмента, stream получает следующий фрагмент из файла в память. Все это происходит на низкоуровневом фоне, пока вы просто перебираете stream. Вот почему он называется stream. ИМХО