C # menggunakan aliran

116

Aliran agak misterius bagi saya. Saya tidak tahu kapan harus menggunakan aliran mana dan bagaimana menggunakannya. Dapatkah seseorang menjelaskan kepada saya bagaimana aliran digunakan?

Jika saya mengerti dengan benar, ada tiga jenis aliran:

  • stream
  • read stream
  • write stream

Apakah ini benar? Dan, misalnya, apa perbedaan antara a Memorystreamdan a FileStream?

Martijn
sumber
13
Anda mungkin ingin memeriksa stackoverflow.com/questions/507747/…
Preets
3
Ambil larik byte dan kemudian buat pembungkus untuk it ( Stream) yang memperlihatkan beberapa metode berguna seperti membaca, menulis dan mengubah posisi. Sekarang Anda dapat membuat kelas berdasarkan penyimpanan dukungan mereka (FileStream, MemoryStream) yang mewarisi dari Streamdan membangun fungsionalitas tersebut berdasarkan penyimpanan dukungan tertentu.
The Muffin Man

Jawaban:

80

Sebuah aliran adalah obyek yang digunakan untuk mentransfer data. Ada kelas aliran generik System.IO.Stream, dari mana semua kelas aliran lainnya di .NET diturunkan. The Streamkelas berkaitan dengan byte.

Kelas aliran konkret digunakan untuk menangani jenis data selain byte. Sebagai contoh:

  • The FileStreamkelas digunakan ketika sumber luar adalah file
  • MemoryStream digunakan untuk menyimpan data di memori
  • System.Net.Sockets.NetworkStream menangani data jaringan

Aliran pembaca / penulis seperti StreamReaderdan StreamWriterbukan aliran - aliran tersebut bukan berasal dari System.IO.Stream, aliran tersebut dirancang untuk membantu menulis dan membaca data dari dan ke streaming!

Arsen Mkrtchyan
sumber
3
Jadi, jika saya mengerti dengan benar, aliran tersebut berisi data dan tidak melakukan apa-apa dengannya. Kelas pembaca dan penulis 'pembantu' dapat menangani (memanipulasi) data di dalam aliran?
Martijn
9
Tidak, Stream bukan wadah data, ini digunakan untuk mentransfer data, misalnya FileStream mentransfer data dari byte [] ke file fisik, NetworkStream mentransfer byte [] dengan soket. Kelas Reader Writer adalah kelas pembantu untuk menulis dan membaca dari aliran, misalnya StreamReader dapat digunakan untuk membaca dari string Stream bukan byte []. jika Anda akan memberikan FileStream sebagai parameter, itu akan dibaca dari File, jika NetworkStream dari soket.
Arsen Mkrtchyan
selain itu, StreamReader dan StreamWriter untuk membaca dan menulis aliran TEXT (karakter).
1c1 paman
1
ada artikel bagus untuk membantu Anda memahami MemoryStream. codeproject.com/Articles/832387/…
Jiaji Li
2
@ pengguna420667. Pertanyaan bagus. Dalam kasus AudioStream dan TemperatureStream, kemungkinan besar keduanya adalah BinaryStreams untuk driver yang terkait dengan perangkat. Atau, Anda dapat membuat CustomStream yang dibuat khusus untuk antarmuka.
1c1 paman
62

Untuk memperluas sedikit jawaban lain di sini, dan membantu menjelaskan banyak contoh kode yang akan Anda lihat bertitik, sebagian besar waktu Anda tidak membaca dan menulis ke aliran secara langsung. Stream adalah sarana tingkat rendah untuk mentransfer data.

Anda akan melihat bahwa semua fungsi untuk membaca dan menulis berorientasi byte, misalnya WriteByte (). Tidak ada fungsi untuk menangani bilangan bulat, string, dll. Hal ini membuat streaming sangat bertujuan umum, tetapi kurang mudah untuk digunakan jika, katakanlah, Anda hanya ingin mentransfer teks.

Namun, .NET menyediakan kelas yang mengonversi antara tipe asli dan antarmuka aliran tingkat rendah, dan mentransfer data ke atau dari aliran untuk Anda. Beberapa kelas terkenal seperti itu adalah:

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

Untuk menggunakannya, pertama-tama Anda memperoleh aliran Anda, kemudian Anda membuat salah satu kelas di atas dan mengaitkannya dengan aliran. Misalnya

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

StreamReader dan StreamWriter mengonversi antara jenis asli dan representasi stringnya, lalu mentransfer string ke dan dari aliran sebagai byte. Begitu

myStreamWriter.Write(123);

akan menulis "123" (tiga karakter '1', '2' lalu '3') ke aliran. Jika Anda berurusan dengan file teks (misalnya html), StreamReader dan StreamWriter adalah kelas yang akan Anda gunakan.

Sedangkan

myBinaryWriter.Write(123);

akan menulis empat byte yang mewakili nilai integer 32-bit 123 (0x7B, 0x00, 0x00, 0x00). Jika Anda berurusan dengan file biner atau protokol jaringan, BinaryReader dan BinaryWriter adalah yang mungkin Anda gunakan. (Jika Anda bertukar data dengan jaringan atau sistem lain, Anda harus memperhatikan ketekunan , tetapi itu adalah pos lain.)

Tim Williams
sumber
Kelas adaptor StreamWriter dan Reader memiliki nama yang sangat buruk. Terima kasih telah menyebutkannya. Kenapa mereka muncul dengan nama ini masih mengejutkan saya.
Tarik
Juga, bahkan kelas penulis dan pembaca biner dinamai dengan buruk.
Tarik
22

Stream bagus untuk menangani data dalam jumlah besar. Jika tidak praktis untuk memuat semua data ke dalam memori pada saat yang sama, Anda dapat membukanya sebagai aliran dan mengerjakannya dengan potongan kecil.

daging
sumber
1
Akan sangat senang melihat contoh dari apa yang baru saja Anda katakan "bekerja dengan potongan kecil".
Jenna Leaf
2
Streaming juga bagus untuk data dalam jumlah kecil. Jika programmer C # ingin memanipulasi isi file, dia harus menggunakan stream, berapa pun jumlah datanya. Pernyataan yang sama juga berlaku untuk aliran jaringan. Memang, jika pemrogram mengkodekan adalah bahasa tingkat rendah seperti C, maka dimungkinkan untuk menulis karakter atau byte secara langsung ke disk atau soket, tetapi bahkan untuk sejumlah kecil data, itu memakan waktu dan lebih rentan terhadap kesalahan.
1c1 paman
10

Stream hanyalah abstraksi (atau pembungkus) di atas physicalaliran byte. Ini physicalaliran disebut base stream. Jadi selalu ada aliran dasar di mana pembungkus aliran dibuat dan dengan demikian pembungkus diberi nama setelah jenis aliran dasar yaitu FileStream, MemoryStreamdll.

Keuntungan dari stream wrapper adalah Anda mendapatkan api terpadu untuk berinteraksi dengan aliran jenis apa pun, usb, filedll.

Mengapa Anda memperlakukan data sebagai aliran - karena potongan data dimuat sesuai permintaan, kami dapat memeriksa / memproses data sebagai potongan daripada memuat seluruh data ke dalam memori. Ini adalah cara sebagian besar program menangani file besar, misalnya mengenkripsi file image OS.

Anwar Husain
sumber
4

Hanya ada satu tipe dasar Stream. Namun dalam berbagai keadaan, beberapa anggota akan mengeluarkan pengecualian saat dipanggil karena dalam konteks itu operasi tidak tersedia.

Misalnya a MemoryStreamhanyalah cara untuk memindahkan byte masuk dan keluar dari sepotong memori. Karenanya Anda dapat memanggil Baca dan Tulis di atasnya.

Di sisi lain a FileStreammemungkinkan Anda untuk membaca atau menulis (atau keduanya) dari / ke file. Apakah Anda benar-benar dapat Membaca atau Menulis tergantung pada bagaimana file dibuka. Anda tidak dapat Menulis ke file jika Anda hanya membukanya untuk akses Baca.

AnthonyWJones
sumber
3

Saya akan mulai dengan membaca streaming di MSDN: http://msdn.microsoft.com/en-us/library/system.io.stream.aspx

Memorystream dan FileStream adalah aliran yang digunakan untuk bekerja dengan memori mentah dan File masing-masing ...

Robban
sumber
Terima kasih untuk tautannya. Saya suka bahwa "Anda dapat menelusuri kode sumber secara online, mengunduh referensi untuk dilihat secara offline, dan menelusuri sumber (termasuk tambalan dan pembaruan) selama debugging". Fitur ini menawarkan tingkat wawasan baru.
David
1

Saya tidak akan menyebut jenis aliran yang berbeda itu. Kelas Stream memiliki properti CanRead dan CanWrite yang memberi tahu Anda apakah aliran tertentu dapat dibaca dan ditulis.

Perbedaan utama antara kelas aliran yang berbeda (seperti MemoryStream vs FileStream) adalah penyimpanan dukungan - tempat data dibaca atau tempat penulisannya. Agak jelas dari namanya. MemoryStream menyimpan data hanya dalam memori, FileStream didukung oleh file pada disk, NetworkStream membaca data dari jaringan dan sebagainya.

Mattias S
sumber