Kata "aliran" telah dipilih karena mewakili (dalam kehidupan nyata) makna yang sangat mirip dengan apa yang ingin kita sampaikan ketika kita menggunakannya.
Mari kita lupakan toko dukungan sebentar, dan mulai berpikir tentang analogi dengan aliran air. Anda menerima aliran data yang berkelanjutan, seperti air yang terus mengalir di sungai. Anda tidak perlu tahu dari mana data berasal, dan paling sering Anda tidak perlu; baik itu dari file, soket, atau sumber lain, itu tidak masalah. Ini sangat mirip dengan menerima aliran air, di mana Anda tidak perlu tahu dari mana asalnya; baik itu dari danau, air mancur, atau sumber lain, itu tidak masalah.
Yang mengatakan, begitu Anda mulai berpikir bahwa Anda hanya peduli untuk mendapatkan data yang Anda butuhkan, terlepas dari mana asalnya, abstraksi yang dibicarakan orang lain menjadi lebih jelas. Anda mulai berpikir bahwa Anda dapat membungkus stream, dan metode Anda akan tetap bekerja dengan sempurna. Misalnya, Anda bisa melakukan ini:
int ReadInt(StreamReader reader) { return Int32.Parse(reader.ReadLine()); }
// in another method:
Stream fileStream = new FileStream("My Data.dat");
Stream zipStream = new ZipDecompressorStream(fileStream);
Stream decryptedStream = new DecryptionStream(zipStream);
StreamReader reader = new StreamReader(decryptedStream);
int x = ReadInt(reader);
Seperti yang Anda lihat, menjadi sangat mudah untuk mengubah sumber input Anda tanpa mengubah logika pemrosesan Anda. Misalnya, untuk membaca data Anda dari soket jaringan alih-alih file:
Stream stream = new NetworkStream(mySocket);
StreamReader reader = new StreamReader(stream);
int x = ReadInt(reader);
Semudah mungkin. Dan keindahan berlanjut, karena Anda dapat menggunakan sumber input apa pun, asalkan Anda dapat membangun aliran "pembungkus" untuk itu. Anda bahkan dapat melakukan ini:
public class RandomNumbersStreamReader : StreamReader {
private Random random = new Random();
public String ReadLine() { return random.Next().ToString(); }
}
// and to call it:
int x = ReadInt(new RandomNumbersStreamReader());
Lihat? Selama metode Anda tidak peduli apa sumber inputnya, Anda dapat menyesuaikan sumber Anda dengan berbagai cara. Abstraksi memungkinkan Anda memisahkan input dari pemrosesan logika dengan cara yang sangat elegan.
Perhatikan bahwa aliran yang kami buat sendiri tidak memiliki backing store, tetapi tetap melayani tujuan kami dengan sempurna.
Jadi, untuk meringkas, aliran hanyalah sumber input, bersembunyi (abstrak) sumber lain. Selama Anda tidak melanggar abstraksi, kode Anda akan sangat fleksibel.
ReadInt
ini didefinisikan di bagian paling atas menggunakanint.Parse
, yang menerima string yang dikembalikan darireader.ReadLine()
dan mem-parsingnya. Tentu saja Anda bisa membuatReadString
metode serupa . Apakah ini cukup jelas?Stream.Copy
membuat hidup jadi lebih mudah di banyak aplikasi.Intinya adalah Anda tidak perlu tahu apa itu backing store - ini abstraksi. Memang, mungkin bahkan tidak ada toko dukungan - Anda bisa membaca dari jaringan, dan data tidak pernah "disimpan" sama sekali.
Jika Anda dapat menulis kode yang berfungsi baik saat Anda sedang berbicara dengan sistem file, memori, jaringan atau apa pun yang mendukung gagasan aliran, kode Anda jauh lebih fleksibel.
Selain itu, aliran sering dirantai bersama - Anda dapat memiliki aliran yang memampatkan apa pun yang dimasukkan ke dalamnya, menulis formulir terkompresi ke aliran lain, atau yang mengenkripsi data, dll. Di sisi lain akan ada kebalikannya rantai, dekripsi, dekompresi atau apa pun.
sumber
StreamReader
- atau lebih baik,TextReader
maka kode Anda tidak tahu jenis aliran apa yang mendasari aliran data. Atau lebih tepatnya, ia bisa menggunakanBaseStream
properti untuk mengetahui tipe - tetapi ini mungkin tipe yang belum pernah dilihat oleh kode Anda. Intinya adalah bahwa Anda seharusnya tidak peduli. Dan ya, Anda benar - benar bisa berakhir menulis kode yang kadang-kadang akan digunakan untuk aliran jaringan dan kadang-kadang digunakan untuk aliran file. Adapun stream data pipa melalui proses - baik yang tidak akan dilakukan di dalam proses ... itu akan menjadi penyedia aliran.Tujuan dari aliran ini adalah untuk memberikan lapisan abstraksi antara Anda dan toko dukungan. Jadi blok kode tertentu yang menggunakan aliran tidak perlu peduli jika toko dukungan adalah file disk, memori, dll ...
sumber
Ini bukan tentang sungai - ini tentang berenang. Jika Anda bisa berenang satu Stream, daripada Anda bisa berenang setiap Stream yang Anda temui.
sumber
Untuk menambah ruang gema, aliran adalah abstraksi sehingga Anda tidak peduli tentang toko yang mendasarinya. Masuk akal jika Anda mempertimbangkan skenario dengan dan tanpa streaming.
Sebagian besar file tidak menarik karena stream tidak melakukan banyak hal di atas dan melampaui metode non-stream yang saya kenal. Mari kita mulai dengan file internet.
Jika saya ingin mengunduh file dari internet, saya harus membuka soket TCP, membuat koneksi, dan menerima byte hingga tidak ada lagi byte. Saya harus mengelola buffer, mengetahui ukuran file yang diharapkan, dan menulis kode untuk mendeteksi ketika koneksi terputus dan menangani ini dengan tepat.
Katakanlah saya memiliki semacam objek TcpDataStream. Saya membuatnya dengan informasi koneksi yang sesuai, kemudian membaca byte dari stream hingga dikatakan tidak ada lagi byte. Aliran menangani manajemen buffer, kondisi data akhir, dan manajemen koneksi.
Dengan cara ini, stream membuat I / O lebih mudah. Anda tentu bisa menulis kelas TcpFileDownloader yang melakukan apa yang dilakukan stream, tetapi kemudian Anda memiliki kelas yang khusus untuk TCP. Kebanyakan antarmuka streaming menyediakan metode Read () dan Write (), dan konsep yang lebih rumit ditangani oleh implementasi internal. Karena itu, Anda dapat menggunakan kode dasar yang sama untuk membaca atau menulis ke memori, file disk, soket, dan banyak penyimpanan data lainnya.
sumber
Visualisasi yang saya gunakan adalah ban berjalan, bukan di pabrik sungguhan karena saya tidak tahu apa-apa tentang itu, tetapi di pabrik kartun tempat barang-barang bergerak di sepanjang garis dan dicap dan dikotak serta dihitung dan diperiksa dengan urutan perangkat bodoh.
Anda memiliki komponen sederhana yang melakukan satu hal, misalnya perangkat untuk meletakkan ceri pada kue. Perangkat ini memiliki aliran input kue tanpa ceri, dan aliran output kue dengan ceri. Ada tiga keuntungan yang layak disebutkan dalam menyusun proses Anda dengan cara ini.
Pertama itu menyederhanakan komponen itu sendiri: jika Anda ingin meletakkan icing cokelat pada kue, Anda tidak perlu perangkat rumit yang tahu segalanya tentang kue, Anda dapat membuat perangkat bodoh yang menempelkan icing cokelat ke apa pun yang dimasukkan ke dalamnya (dalam kartun, sejauh ini tidak mengetahui bahwa item berikutnya bukan kue, itu Wile E. Coyote).
Kedua, Anda dapat membuat produk yang berbeda dengan menempatkan perangkat ke dalam urutan yang berbeda: mungkin Anda ingin kue Anda memiliki lapisan gula di atas ceri, bukan ceri di atas lapisan gula, dan Anda dapat melakukannya hanya dengan menukar perangkat di sekitar pada baris .
Ketiga, perangkat tidak perlu mengelola inventaris, tinju, atau unboxing. Cara paling efisien untuk menggabungkan dan mengemas barang-barang bisa diubah: mungkin hari ini Anda memasukkan kue Anda ke dalam kotak berisi 48 dan mengirimkannya ke luar truk, tetapi besok Anda ingin mengirimkan kotak enam untuk menanggapi pesanan khusus. Perubahan semacam ini dapat diakomodir dengan mengganti atau mengkonfigurasi ulang mesin pada awal dan akhir jalur produksi; mesin ceri di tengah baris tidak harus diubah untuk memproses jumlah item yang berbeda pada satu waktu, itu selalu bekerja dengan satu item pada suatu waktu dan tidak harus tahu bagaimana input atau outputnya dikelompokkan.
sumber
Ketika saya mendengar tentang streaming untuk pertama kalinya, itu dalam konteks streaming langsung dengan webcam. Jadi, satu host menyiarkan konten video, dan host lainnya menerima konten video. Jadi, apakah streaming ini? Yah ... ya ... tapi streaming langsung adalah konsep konkret, dan saya pikir pertanyaannya mengacu pada konsep abstrak Streaming. Lihat https://en.wikipedia.org/wiki/Live_streaming
Jadi mari kita lanjutkan.
Video bukan satu-satunya sumber daya yang dapat dialirkan. Audio juga dapat di-stream. Jadi kita berbicara tentang Streaming media sekarang. Lihat https://en.wikipedia.org/wiki/Streaming_media . Audio dapat dikirim dari sumber ke target dengan berbagai cara. Jadi mari kita bandingkan beberapa metode pengiriman data satu sama lain.
Pengunduhan file klasik Pengunduhan file klasik tidak terjadi dalam waktu nyata. Sebelum mengambil file untuk digunakan, Anda harus menunggu sampai unduhan selesai.
Unduhan progresif Potongan unduhan progresif mengunduh data dari file media yang dialirkan ke buffer sementara. Data dalam buffer itu bisa diterapkan: data audio-video dalam buffer dapat dimainkan. Karena itu pengguna dapat menonton / mendengarkan file media streaming saat mengunduh. Fast-forwarding dan rewinding adalah mungkin, offcourse dengan buffer. Bagaimanapun, pengunduhan progresif bukanlah streaming langsung.
Streaming Terjadi real-time, dan memotong data. Streaming diimplementasikan dalam siaran langsung. Klien yang mendengarkan siaran tidak bisa maju atau mundur cepat. Dalam video stream, data dibuang setelah pemutaran.
Server Streaming menyimpan koneksi 2 arah dengan kliennya, sementara Server Web menutup koneksi setelah respons server.
Audio dan video bukan satu-satunya hal yang dapat dialirkan. Mari kita lihat konsep stream dalam manual PHP.
Dalam PHP, sumber daya adalah referensi ke sumber eksternal seperti file, koneksi database. Jadi dengan kata lain, stream adalah sumber yang dapat dibaca atau ditulis. Jadi, Jika Anda bekerja dengan
fopen()
, maka Anda sudah bekerja dengan stream.Contoh file teks yang mengalami Streaming:
File zip juga dapat di-stream. Selain itu, streaming tidak terbatas pada file. HTTP, FTP, koneksi SSH dan Input / Output dapat di-stream juga.
Apa yang dikatakan wikipedia tentang konsep Streaming?
Lihat: https://en.wikipedia.org/wiki/Stream_%28computing%29 .
Tautan Wikipedia ke ini: https://srfi.schemers.org/srfi-41/srfi-41.html dan penulisnya mengatakan ini tentang stream:
Jadi Stream sebenarnya adalah struktur data.
Kesimpulan saya: stream adalah sumber yang dapat berisi data yang dapat dibaca dari atau ditulis secara berurutan. Aliran tidak membaca semua yang berisi sumber sekaligus, ia membaca / menulis secara berurutan.
Tautan bermanfaat:
sumber
Itu hanya sebuah konsep, tingkat abstraksi lain yang membuat hidup Anda lebih mudah. Dan mereka semua memiliki antarmuka umum yang berarti Anda dapat menggabungkan mereka dalam cara seperti pipa. Sebagai contoh, encode ke base64, lalu zip lalu tulis ini ke disk dan semuanya dalam satu baris!
sumber
Penjelasan terbaik aliran yang pernah saya lihat adalah bab 3 dari SICP . (Anda mungkin perlu membaca 2 bab pertama agar masuk akal, tetapi Anda harus tetap melakukannya. :-)
Mereka tidak menggunakan sterams untuk byte sama sekali, melainkan bilangan bulat. Poin besar yang saya dapatkan dari itu adalah:
sumber
Poin lain (Untuk membaca situasi file):
stream
dapat memungkinkan Anda untuk melakukan sesuatu yang lain sebelumnyafinished reading all content of the file
.sumber
Pikirkan stream sebagai sumber data abstrak (byte, karakter, dll.). Mereka abstrak mekanisme aktual membaca dari dan menulis ke sumber data konkret, baik itu soket jaringan, file pada disk atau tanggapan dari server web.
sumber
Saya pikir Anda perlu mempertimbangkan bahwa backing store itu sendiri seringkali hanyalah abstraksi lain. Aliran memori cukup mudah dimengerti, tetapi file berbeda secara radikal tergantung pada sistem file yang Anda gunakan, apa pun hard drive yang Anda gunakan. Tidak semua stream benar-benar duduk di atas sebuah backing store: aliran jaringan cukup banyak adalah stream.
Inti dari aliran adalah bahwa kita membatasi perhatian kita pada apa yang penting. Dengan memiliki abstraksi standar, kita dapat melakukan operasi umum. Bahkan jika Anda tidak ingin, misalnya, mencari file atau respons HTTP untuk URL hari ini, tidak berarti Anda tidak ingin melakukannya besok.
Aliran awalnya dikandung ketika memori kecil dibandingkan dengan penyimpanan. Hanya membaca file C bisa menjadi beban yang signifikan. Meminimalkan jejak memori sangat penting. Karenanya, sebuah abstraksi di mana sangat sedikit yang perlu dimuat sangat berguna. Saat ini, sama-sama berguna ketika melakukan komunikasi jaringan dan, ternyata, jarang membatasi ketika kita berurusan dengan file. Kemampuan untuk menambahkan hal-hal seperti buffering secara transparan membuatnya lebih berguna.
sumber
Aliran adalah abstrak dari urutan byte. Idenya adalah bahwa Anda tidak perlu tahu dari mana byte berasal, hanya saja Anda dapat membacanya secara standar.
Misalnya, jika Anda memproses data melalui aliran maka tidak masalah dengan kode Anda jika data berasal dari file, koneksi jaringan, string, gumpalan di database dll. Dll.
Tidak ada yang salah dengan berinteraksi dengan backing store itu sendiri kecuali kenyataan bahwa itu mengikat Anda dengan implementasi backing store.
sumber
Aliran adalah abstraksi yang menyediakan sekumpulan metode dan properti standar untuk berinteraksi dengan data. Dengan mengabstraksi dari media penyimpanan yang sebenarnya, kode Anda dapat ditulis tanpa bergantung sepenuhnya pada apa media itu atau bahkan implementasi media itu.
Analogi yang baik mungkin untuk mempertimbangkan tas. Anda tidak peduli terbuat dari apa tas atau apa fungsinya ketika Anda meletakkan barang-barang Anda di dalamnya, selama tas melakukan pekerjaan menjadi tas dan Anda bisa mendapatkan barang-barang Anda kembali. Sebuah aliran mendefinisikan untuk media penyimpanan apa konsep tas mendefinisikan untuk berbagai contoh tas (seperti tas sampah, tas tangan, ransel, dll.) - aturan interaksi.
sumber
Saya akan singkat, saya hanya kehilangan kata di sini:
Streaming adalah antrian yang biasanya disimpan dalam buffer yang berisi segala jenis data.
(Sekarang, karena kita semua tahu apa itu antrian, tidak perlu menjelaskan ini lebih jauh.)
sumber