C # с использованием потоков - PullRequest
101 голосов
/ 10 сентября 2009

Потоки для меня загадочны. Я не знаю, когда использовать какой поток и как их использовать. Может кто-нибудь объяснить мне, как используются потоки?

Если я правильно понимаю, есть три типа потока:

  • stream
  • read stream
  • write stream

Это правильно? И, например, в чем разница между Memorystream и FileStream?

Ответы [ 7 ]

65 голосов
/ 10 сентября 2009

A stream - объект, используемый для передачи данных. Существует универсальный класс потока System.IO.Stream, из которого получены все остальные классы потока в .NET. Класс Stream имеет дело с байтами.

Конкретные классы потока используются для работы с другими типами данных, кроме байтов. Например:

  • Класс FileStream используется, когда внешним источником является файл
  • MemoryStream используется для хранения данных в памяти
  • System.Net.Sockets.NetworkStream обрабатывает данные сети

Потоки Reader / Writer, такие как StreamReader и StreamWriter, не являются потоками - они не являются производными от System.IO.Stream, они предназначены для помощи в записи и чтении данных из и в поток!

49 голосов
/ 31 мая 2013

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

Вы заметите, что все функции для чтения и записи ориентированы на байты, например, WriteByte (). Нет функций для работы с целыми числами, строками и т. Д. Это делает поток очень универсальным, но с ним проще работать, если, скажем, вы просто хотите передать текст.

Однако .NET предоставляет классы, которые конвертируют между нативными типами и интерфейсом низкоуровневого потока и передают данные в или из потока для вас. Некоторые известные такие классы:

StreamWriter // Badly named. Should be TextWriter.
StreamReader // Badly named. Should be TextReader.
BinaryWriter
BinaryReader

Чтобы использовать их, сначала вы получаете ваш поток, затем вы создаете один из вышеперечисленных классов и связываете его с потоком. Э.Г.

MemoryStream memoryStream = new MemoryStream();
StreamWriter myStreamWriter = new StreamWriter(memoryStream);

StreamReader и StreamWriter преобразуют между нативными типами и их строковыми представлениями, а затем передают строки в поток и из потока в виде байтов. Так

myStreamWriter.Write(123);

запишет «123» (три символа «1», «2», а затем «3») в поток. Если вы имеете дело с текстовыми файлами (например, html), StreamReader и StreamWriter - это те классы, которые вы бы использовали.

Принимая во внимание

myBinaryWriter.Write(123);

запишет четыре байта, представляющих 32-разрядное целочисленное значение 123 (0x7B, 0x00, 0x00, 0x00). Если вы имеете дело с двоичными файлами или сетевыми протоколами, BinaryReader и BinaryWriter - это то, что вы можете использовать. (Если вы обмениваетесь данными с сетями или другими системами, вам нужно помнить о endianness , но это другой пост.)

20 голосов
/ 10 сентября 2009

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

5 голосов
/ 20 июля 2016

Stream - это просто абстракция (или оболочка) над physical потоком байтов. Этот поток physical называется base stream. Таким образом, всегда существует базовый поток, над которым создается потоковая оболочка, и, таким образом, оболочка получает имя в соответствии с типом базового потока, то есть FileStream, MemoryStream и т. Д.

Преимущество потоковой оболочки заключается в том, что вы получаете унифицированный API для взаимодействия с потоками любого базового типа usb, file и т. Д.

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

4 голосов
/ 10 сентября 2009

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

Например, MemoryStream - это просто способ перемещения байтов в кусок памяти и из него. Следовательно, вы можете позвонить «Чтение и запись».

С другой стороны, FileStream позволяет вам читать или записывать (или оба) из / в файл. Возможность чтения или записи зависит от того, как был открыт файл. Вы не можете записать в файл, если открыли его только для чтения.

3 голосов
/ 10 сентября 2009

Я бы начал с чтения потоков в MSDN: http://msdn.microsoft.com/en-us/library/system.io.stream.aspx

Memorystream и FileStream - это потоки, используемые для работы с необработанной памятью и файлами соответственно ...

1 голос
/ 10 сентября 2009

Я бы не назвал эти разные виды потоков. Класс Stream имеет свойства CanRead и CanWrite, которые сообщают вам, можно ли считывать и записывать конкретный поток.

Основное различие между различными классами потоков (такими как MemoryStream и FileStream) заключается в резервном хранилище - откуда данные считываются или куда записываются. Это как бы видно из названия. MemoryStream хранит данные только в памяти, FileStream поддерживается файлом на диске, NetworkStream читает данные из сети и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...