Apa itu stream?


Jawaban:


161

Aliran mewakili urutan objek (biasanya byte, tetapi tidak harus demikian), yang dapat diakses secara berurutan. Operasi khas pada aliran:

  • baca satu byte. Lain kali Anda membaca, Anda akan mendapatkan byte berikutnya, dan seterusnya.
  • membaca beberapa byte dari aliran ke array
  • seek (pindahkan posisi Anda saat ini di arus, sehingga saat berikutnya Anda membaca Anda mendapatkan byte dari posisi baru)
  • tulis satu byte
  • tulis beberapa byte dari array ke dalam stream
  • lewati byte dari aliran (ini seperti membaca, tetapi Anda mengabaikan data. Atau jika Anda lebih suka seperti mencari tetapi hanya bisa maju.)
  • dorong kembali byte ke aliran input (ini seperti "undo" untuk dibaca - Anda mendorong beberapa byte cadangan aliran, sehingga lain kali Anda membaca itu yang akan Anda lihat. Kadang-kadang berguna untuk parser, seperti:
  • mengintip (lihat byte tanpa membacanya, sehingga masih ada di aliran untuk dibaca nanti)

Aliran tertentu mungkin mendukung pembacaan (dalam hal ini merupakan "aliran input"), penulisan ("aliran keluaran") atau keduanya. Tidak semua aliran dapat dicari.

Dorong kembali cukup jarang, tetapi Anda selalu dapat menambahkannya ke aliran dengan membungkus aliran input nyata di aliran input lain yang menampung buffer internal. Bacaan berasal dari buffer, dan jika Anda mendorong kembali maka data ditempatkan di buffer. Jika tidak ada apa-apa di buffer maka aliran balik membaca dari aliran nyata. Ini adalah contoh sederhana "adaptor aliran": ia berada di "ujung" aliran input, itu adalah aliran input itu sendiri, dan ia melakukan sesuatu yang ekstra yang tidak dilakukan oleh aliran asli.

Streaming adalah abstraksi yang berguna karena dapat menggambarkan file (yang benar-benar array, maka pencarian mudah) tetapi juga terminal input / output (yang tidak dapat dicari kecuali buffered), soket, port serial, dll. Jadi Anda dapat menulis kode yang mengatakan baik "Saya ingin beberapa data, dan saya tidak peduli dari mana asalnya atau bagaimana data itu sampai di sini", atau "Saya akan menghasilkan beberapa data, dan sepenuhnya tergantung pada penelepon saya apa yang terjadi padanya". Yang pertama mengambil parameter aliran input, yang terakhir mengambil parameter aliran output.

Analogi terbaik yang bisa saya pikirkan adalah bahwa arus adalah sabuk konveyor yang menghampiri Anda atau menjauh dari Anda (atau kadang-kadang keduanya). Anda mengambil barang dari aliran input, Anda meletakkan barang di aliran output. Beberapa konveyor yang Anda anggap keluar dari lubang di dinding - konveyor tidak dapat dicari, membaca atau menulis adalah kesepakatan satu kali saja. Beberapa konveyor diletakkan di depan Anda, dan Anda dapat bergerak bersama memilih keberadaan di aliran yang ingin Anda baca / tulis - yang dicari.

Namun, seperti dikatakan IRBMe, yang terbaik adalah memikirkan aliran dalam hal operasi yang ditawarkannya (yang bervariasi dari implementasi ke implementasi, tetapi memiliki banyak kesamaan) daripada dengan analogi fisik. Streaming adalah "hal-hal yang dapat Anda baca atau tulis". Ketika Anda mulai menghubungkan adaptor aliran, Anda dapat menganggapnya sebagai sebuah kotak dengan konveyor masuk, dan konveyor keluar, yang Anda sambungkan ke aliran lain dan kemudian kotak tersebut melakukan beberapa transformasi pada data (zip, atau mengubah umpan baris UNIX). untuk yang DOS, atau apa pun). Pipes adalah tes menyeluruh lain dari metafora: di situlah Anda membuat sepasang aliran sehingga apa pun yang Anda tulis menjadi satu dapat dibaca dari yang lain. Pikirkan lubang cacing :-)


3
Sejauh ini penjelasan terbaik yang pernah saya baca. Ditambah dengan apa yang tertulis di SICP ("Pemrosesan aliran memungkinkan kita memodelkan sistem yang memiliki status tanpa pernah menggunakan tugas atau data yang bisa diubah."), Pikir saya akhirnya mendapatkannya. Terima kasih!
Kyle Chadha

85

Aliran sudah menjadi metafora, analogi, jadi benar-benar tidak perlu untuk membagi yang lain. Anda dapat menganggapnya pada dasarnya sebagai pipa dengan aliran air di dalamnya di mana air sebenarnya adalah data dan pipa adalah aliran. Saya kira itu semacam pipa 2 arah jika alirannya dua arah. Ini pada dasarnya adalah abstraksi umum yang ditempatkan pada hal-hal di mana ada aliran atau urutan data dalam satu atau kedua arah.

Dalam bahasa seperti C #, VB.Net, C ++, Java dll., Metafora aliran digunakan untuk banyak hal. Ada aliran file, di mana Anda membuka file dan dapat membaca dari aliran atau menulis ke sana terus menerus; Ada aliran jaringan di mana membaca dari dan menulis ke aliran membaca dari dan menulis ke koneksi jaringan mapan yang mendasarinya. Aliran hanya untuk penulisan biasanya disebut aliran keluaran, seperti dalam contoh ini , dan demikian pula, aliran yang hanya untuk membaca disebut aliran input, seperti dalam contoh ini .

Aliran dapat melakukan transformasi atau penyandian data ( SslStream di .Net, misalnya, akan memakan data negosiasi SSL dan menyembunyikannya dari Anda; TelnetStream mungkin menyembunyikan negosiasi Telnet dari Anda, tetapi memberikan akses ke data; A ZipOutputStream di Jawa memungkinkan Anda untuk menulis ke file dalam arsip zip tanpa harus khawatir tentang internal format file zip.

Hal umum lainnya yang mungkin Anda temukan adalah aliran teks yang memungkinkan Anda untuk menulis string, bukan byte, atau beberapa bahasa menyediakan aliran biner yang memungkinkan Anda untuk menulis tipe primitif. Hal umum yang akan Anda temukan di aliran teks adalah pengkodean karakter, yang harus Anda perhatikan.

Beberapa aliran juga mendukung akses acak, seperti dalam contoh ini . Aliran jaringan, di sisi lain, untuk alasan yang jelas, tidak akan.

  • MSDN memberikan gambaran umum aliran di .Net.
  • Sun juga memiliki gambaran umum tentang kelas OutputStream umum dan kelas InputStream .
  • Dalam C ++, berikut adalah dokumentasi istream (input stream), ostream (output stream) dan iostream (bidirectional stream).

Sistem operasi seperti UNIX juga mendukung model aliran dengan input dan output program, seperti dijelaskan di sini .


13

Jawaban yang diberikan sejauh ini sangat bagus. Saya hanya menyediakan yang lain untuk menyoroti bahwa aliran bukan urutan byte atau khusus untuk bahasa pemrograman karena konsepnya universal (sementara implementasinya mungkin unik). Saya sering melihat banyak sekali penjelasan online dalam hal SQL, atau C atau Java, yang masuk akal sebagai sebuah penawaran filestream dengan lokasi memori dan operasi tingkat rendah. Tetapi mereka sering membahas bagaimana membuat filestream dan beroperasi pada file potensial dalam bahasa yang diberikan daripada mendiskusikan konsep stream.

Metafora

Seperti disebutkan a streamadalah metafora, abstraksi dari sesuatu yang lebih kompleks. Untuk membuat imajinasi Anda bekerja, saya menawarkan beberapa metafora lain:

  1. Anda ingin mengisi kolam kosong dengan air. salah satu cara untuk mencapai ini adalah dengan memasang selang ke keran, menempatkan ujung selang di kolam dan menyalakan air.

selang adalah aliran

  1. sama halnya, jika Anda ingin mengisi ulang mobil Anda dengan gas, Anda akan pergi ke pompa bensin, memasukkan nozzle ke dalam tangki gas Anda dan membuka katup dengan menekan tuas pengunci.

selang, nosel dan mekanisme terkait untuk memungkinkan gas mengalir ke tangki Anda adalah aliran

  1. jika Anda harus mulai bekerja, Anda akan mulai berkendara dari rumah ke kantor menggunakan jalan bebas hambatan.

jalan bebas hambatan adalah arus

  1. jika Anda ingin berbicara dengan seseorang, Anda akan menggunakan telinga Anda untuk mendengar dan mulut Anda untuk berbicara.

telinga dan matamu seperti aliran

Mudah-mudahan Anda perhatikan dalam contoh-contoh ini bahwa metafora aliran hanya ada untuk memungkinkan sesuatu untuk melewatinya (atau di atasnya dalam kasus jalan bebas hambatan) dan tidak dengan sendirinya selalu menampilkan hal yang mereka transfer. Perbedaan penting. Kami tidak menyebut telinga kami sebagai urutan kata-kata. Selang masih merupakan selang jika tidak ada air yang mengalir melewatinya, tetapi kita harus menghubungkannya ke keran untuk melakukan tugasnya dengan benar. Mobil bukan satu-satunya 'jenis' kendaraan yang dapat melintasi jalan bebas hambatan.

Dengan demikian aliran dapat ada yang tidak memiliki data yang melewatinya asalkan terhubung ke file .

Menghapus Abstraksi

Selanjutnya, kita perlu menjawab beberapa pertanyaan. Saya akan menggunakan file untuk menjelaskan aliran jadi ... Apa itu file? Dan bagaimana kita membaca file? Saya akan mencoba menjawab ini sambil mempertahankan tingkat abstraksi tertentu untuk menghindari kerumitan yang tidak perlu dan akan menggunakan konsep file relatif terhadap sistem operasi linux karena kesederhanaan dan aksesibilitasnya.

Apa itu file?

File adalah abstraksi :)

Atau, sesederhana yang saya bisa jelaskan, file adalah satu bagian struktur data yang menggambarkan file dan satu bagian data yang merupakan konten aktual.

Bagian struktur data (disebut inode dalam sistem UNIX / linux) mengidentifikasi informasi penting tentang konten, tetapi tidak menyertakan konten itu sendiri (atau nama file dalam hal ini). Salah satu bagian dari informasi yang disimpannya adalah alamat memori tempat konten dimulai. Jadi dengan nama file (atau hard link di linux), deskriptor file (nama file numerik yang dipedulikan sistem operasi) dan lokasi awal dalam memori kita memiliki sesuatu yang dapat kita sebut file.

(kuncinya adalah 'file' didefinisikan oleh sistem operasi karena itu adalah OS yang akhirnya harus menghadapinya. dan ya, file jauh lebih kompleks).

Sejauh ini baik. Tapi bagaimana cara kami mendapatkan konten file, katakan surat cinta kepada kekasih Anda, sehingga kami dapat mencetaknya?

Membaca file

Jika kita mulai dari hasil dan mundur, ketika kita membuka file di komputer kita seluruh isinya terciprat di layar untuk dibaca. Tapi bagaimana caranya? Sangat metodis jawabannya. Isi file itu sendiri adalah struktur data lain. Misalkan array karakter. Kita juga bisa menganggap ini sebagai string.

Jadi bagaimana kita 'membaca' string ini? Dengan menemukan lokasinya di memori dan mengulangi susunan karakter kami, satu karakter sekaligus hingga mencapai akhir karakter file. Dengan kata lain suatu program.

Aliran 'dibuat' saat programnya dipanggil dan memiliki lokasi memori untuk dilampirkan atau disambungkan . Sama seperti contoh selang air kami, selang tidak efektif jika tidak terhubung ke keran. Dalam hal aliran, itu harus terhubung ke file agar ada.

Streaming dapat disempurnakan lebih lanjut, misalnya aliran untuk menerima input atau aliran untuk mengirim konten file ke output standar. UNIX / linux menghubungkan dan tetap membuka 3 filestream untuk kita langsung dari bat, stdin (input standar), stdout (output standar) dan stderr (standard error). Streaming dapat dibangun sebagai struktur data itu sendiri atau objek yang memungkinkan kita untuk melakukan operasi yang lebih kompleks dari streaming data melalui mereka, seperti membuka aliran, menutup aliran atau kesalahan memeriksa file aliran terhubung. C ++ cinadalah contoh dari objek stream.

Tentunya, jika Anda memilihnya, Anda dapat menulis aliran Anda sendiri.

Definisi

Aliran adalah bagian kode yang dapat digunakan kembali yang mengabstraksi kompleksitas berurusan dengan data sambil memberikan operasi yang berguna untuk dilakukan pada data.


Jadi stream adalah media melalui mana data mengalir. Itu harus terhubung ke sumber data, dan dapat melakukan operasi itu sendiri dan data mengalir melaluinya.
KingBryan

Iya. satu-satunya alasan saya untuk menulis jawaban tambahan adalah untuk mengklarifikasi bahwa aliran dapat ada bahkan jika data tidak mengalir melaluinya. sedangkan aliran IRL (dengan air dan semacamnya) berhenti menjadi aliran ketika air berhenti mengalir dan dapat menyebabkan kebingungan ketika memikirkan analoginya.
rekurzion

1
Saat ini saya sedang belajar Java, dan jawaban Anda membantu saya merangkul kepala saya.
KingBryan

6

Selain hal-hal yang disebutkan di atas ada berbagai aliran - seperti yang didefinisikan dalam bahasa pemrograman fungsional seperti Skema atau Haskell - sebuah struktur data yang mungkin tak terbatas yang dihasilkan oleh beberapa fungsi sesuai permintaan.


6

Analogi lain: Anda tidak bisa berenang melawan arus, itu sebabnya Anda bisa mengambil bit, byte, string atau objek berikutnya dari aliran, sementara data yang sudah dibaca dihapus. Tiket satu arah ... atau pada dasarnya hanya antrian tanpa menyimpan kegigihan.

Jadi, apakah kita perlu antrian? Kamu putuskan.


itu berarti bahwa dalam aliran, kamu harus maju tidak dapat bergerak mundur. Selain itu data sebelumnya dihapus karena Anda maju yang menyimpan memori? Benar
Muhammad Faizan Khan

5

Kata "aliran" telah dipilih karena mewakili (dalam kehidupan nyata) makna yang sangat mirip dengan apa yang ingin kita sampaikan ketika kita menggunakannya.

Mulailah 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. sumber

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.