Bir akış nedir?


Yanıtlar:


161

Akış, sıralı sırayla erişilebilen bir dizi nesneyi temsil eder (genellikle bayttır, ancak böyle olması gerekmez). Bir akış üzerindeki tipik işlemler:

  • bir bayt oku. Bir dahaki sefere okuduğunuzda, bir sonraki baytı alırsınız ve bu böyle devam eder.
  • akıştan bir diziye birkaç baytı oku
  • arama (akıştaki mevcut konumunuzu taşıyın, böylece bir dahaki sefere yeni konumunuzdan bayt alırsınız)
  • bir bayt yaz
  • Bir diziden akışa birkaç bayt yaz
  • Akıştaki baytları atlayın (bu okuma gibidir, ancak verileri görmezden gelirsiniz. Veya tercih ederseniz, arama gibidir ancak yalnızca ileri gidebilir.)
  • baytları bir giriş akışına geri itin (bu, okumak için "geri almak" gibidir - akışı birkaç bayt geri alırsınız, böylece bir dahaki sefere okuyacağınız şey budur. Olduğu gibi ayrıştırıcılar için ara sıra yararlıdır:
  • gözetleme (baytlara okumadan bakın, böylece daha sonra okunmak üzere akışta hala orada olurlar)

Belirli bir akış, okumayı (bu durumda bir "giriş akışı" dır), yazmayı ("çıktı akışı") veya her ikisini de destekleyebilir. Tüm akışlar aranamaz.

Geri itme oldukça nadirdir, ancak gerçek giriş akışını dahili bir arabelleği tutan başka bir giriş akışına sararak her zaman bunu bir akışa ekleyebilirsiniz. Okumalar arabellekten gelir ve geri gönderirseniz veriler arabelleğe yerleştirilir. Tamponda hiçbir şey yoksa, geri itme akışı gerçek akıştan okur. Bu, bir "akış bağdaştırıcısı" nın basit bir örneğidir: bir girdi akışının "ucunda" bulunur, bir girdi akışının kendisidir ve orijinal akışın yapmadığı fazladan bir şey yapar.

Akış yararlı bir soyutlamadır çünkü dosyaları (bunlar gerçekten dizilerdir, dolayısıyla arama basittir), aynı zamanda terminal giriş / çıkışını (arabelleğe alınmadıkça aranamaz), soketleri, seri bağlantı noktalarını vb. Tanımlayabilir. Böylece, yazan kodu yazabilirsiniz. ya "Biraz veri istiyorum ve nereden geldiği ya da buraya nasıl geldiği umurumda değil" ya da "Biraz veri üreteceğim ve ona ne olacağı tamamen arayanıma kalmış". İlki bir giriş akışı parametresi alır, ikincisi bir çıkış akışı parametresi alır.

Aklıma gelen en iyi benzetme, bir akışın size doğru gelen veya sizden uzaklaşan (veya bazen her ikisinin de) bir konveyör bandı olmasıdır. Bir giriş akışından bir şeyler alırsınız, bir çıkış akışına bir şeyler koyarsınız. Duvardaki bir delikten çıktığını düşünebileceğiniz bazı konveyörler - aranamazlar, okumak veya yazmak tek seferlik bir anlaşma. Bazı taşıyıcılar önünüze yerleştirilmiştir ve okumak / yazmak istediğiniz akışta nerede olduğunu seçerek hareket edebilirsiniz - bu aramaktır.

IRBMe'nin dediği gibi, bir akışı fiziksel bir benzetmeden ziyade sunduğu işlemler (uygulamadan uygulamaya değişir, ancak pek çok ortak noktası vardır) açısından düşünmek en iyisidir. Akışlar, "okuyabileceğiniz veya yazabileceğiniz şeylerdir". Akış adaptörlerini bağlamaya başladığınızda, bunları diğer akışlara bağladığınız bir konveyör ve bir konveyör çıkışı olan bir kutu olarak düşünebilirsiniz ve ardından kutu veriler üzerinde bir miktar dönüşüm gerçekleştirir (sıkıştırarak veya UNIX satır beslemelerini değiştirir) DOS olanlar veya her neyse). Borular, metaforun başka bir kapsamlı testidir: Birine yazdığınız her şeyin diğerinden okunabilmesi için bir çift akış oluşturduğunuz yerdir. Solucan deliklerini düşünün :-)


3
Şu ana kadar okuduğum en iyi açıklama. SICP'de söyledikleriyle birleştiğinde ("Akış işleme, atama veya değiştirilebilir verileri kullanmadan duruma sahip sistemleri modellememize olanak tanır."), Sonunda anladığımı düşünüyorum. Teşekkür ederim!
Kyle Chadha

86

Bir akış zaten bir metafor, bir benzetmedir, bu yüzden gerçekten başka birini düşünmeye gerek yoktur. Bunu temelde içinde su akışı olan bir boru olarak düşünebilirsiniz; burada su gerçekte veri ve borunun akış olduğu. Akıntı iki yönlü ise sanırım 2 yönlü bir boru. Temelde, bir veya iki yönde bir veri akışı veya dizisi olan şeylere yerleştirilen ortak bir soyutlamadır.

C #, VB.Net, C ++, Java vb. Dillerde akım metaforu birçok şey için kullanılır. Bir dosyayı açtığınız ve akıştan okuyabileceğiniz veya ona sürekli olarak yazabileceğiniz dosya akışları vardır; Akıştan okuma ve akışa yazmanın, temelde kurulmuş bir ağ bağlantısından okuduğu ve ona yazdığı ağ akışları vardır. Yalnızca yazma amaçlı akışlar, bu örnekte olduğu gibi tipik olarak çıkış akışları olarak adlandırılır ve benzer şekilde, yalnızca okuma amaçlı akışlar, bu örnekte olduğu gibi giriş akışları olarak adlandırılır .

Bir akış, verilerin dönüştürülmesini veya kodlanmasını gerçekleştirebilir ( örneğin .Net'teki bir SslStream , SSL görüşme verilerini yer ve sizden gizler; Bir TelnetStream, Telnet görüşmelerini sizden gizleyebilir, ancak verilere erişim sağlayabilir; A ZipOutputStream , zip dosya biçiminin dahili özellikleri hakkında endişelenmenize gerek kalmadan bir zip arşivindeki dosyalara yazmanıza olanak tanır.

Bulabileceğiniz diğer bir yaygın şey, bayt yerine dizeler yazmanıza izin veren metinsel akışlardır veya bazı diller, ilkel türler yazmanıza izin veren ikili akışlar sağlar. Metin akışlarında bulacağınız yaygın bir şey, bilmeniz gereken bir karakter kodlamasıdır.

Bu örnekte olduğu gibi bazı akışlar da rastgele erişimi destekler . Öte yandan, bariz nedenlerden dolayı bir ağ akışı olmaz.

  • MSDN , .Net'teki akışlara iyi bir genel bakış sağlar.
  • Sun ayrıca genel OutputStream sınıflarına ve InputStream sınıflarına genel bir bakış sunar .
  • C ++ 'da istream (giriş akışı), ostream (çıkış akışı) ve iostream (çift yönlü akış) belgeleri burada.

UNIX benzeri işletim sistemleri de burada açıklandığı gibi program girişi ve çıkışı ile akış modelini destekler .


13

Şimdiye kadar verilen cevaplar mükemmel. Kavram evrensel olduğu için akışın bayt dizisi olmadığını veya bir programlama diline özgü olmadığını vurgulamak için yalnızca başka bir tane sağlıyorum (uygulaması benzersiz olabilir). Sıklıkla SQL, C veya Java açısından çok sayıda çevrimiçi açıklama görüyorum; bu, bir dosya akışı bellek konumları ve düşük seviyeli işlemlerle uğraştığı için mantıklıdır. Ancak, genellikle bir akış kavramını tartışmak yerine, bir filestream oluşturmayı ve potansiyel dosya üzerinde kendi dillerinde nasıl işlem yapacaklarını ele alırlar.

Metafor

Bahsedildiği gibi a streambir metafordur, daha karmaşık bir şeyin soyutlamasıdır. Hayal gücünüzü çalıştırmak için başka metaforlar sunuyorum:

  1. boş bir havuzu suyla doldurmak istiyorsunuz. Bunu başarmanın bir yolu, hortum ağzına bir hortum takmak, hortumun ucunu havuza yerleştirmek ve suyu açmaktır.

hortum akıntıdır

  1. Benzer şekilde, arabanıza gaz doldurmak isterseniz, bir benzin pompasına gider, nozulu gaz tankınıza sokar ve kilitleme kolunu sıkarak vanayı açarsınız.

gazın tankınıza akmasına izin veren hortum, nozul ve ilgili mekanizmalar akıştır

  1. Eğer işe gitmeniz gerekiyorsa, otobanı kullanarak evinizden ofise gitmeye başlayacaksınız.

otoban akıntıdır

  1. Biriyle konuşmak isterseniz, duymak için kulaklarınızı ve konuşmak için ağzınızı kullanırsınız.

kulakların ve gözlerin akıntı

Umarım bu örneklerde, akış metaforlarının yalnızca bir şeyin içinden geçmesine izin vermek için var olduğunu (veya otoyol söz konusu olduğunda) ve kendilerinin her zaman aktardıkları şeyi ortaya koymadığını fark etmişsinizdir. Önemli bir ayrım. Kulaklarımızı bir dizi kelime olarak adlandırmayız. İçinden su akmıyorsa hortum hala bir hortumdur, ancak işini doğru yapması için onu bir musluğa bağlamamız gerekir. Araba, bir otobanı geçebilen tek 'tür' araç değildir.

Böylece , bir dosyaya bağlı olduğu sürece içinden veri geçmeyen bir akış mevcut olabilir. .

Soyutlamayı Kaldırma

Sonra, birkaç soruyu yanıtlamamız gerekiyor. Akışları tanımlamak için dosyaları kullanacağım, bu yüzden ... Dosya nedir? Ve bir dosyayı nasıl okuruz? Gereksiz karmaşıklığı önlemek için belirli bir soyutlama seviyesini korurken buna cevap vermeye çalışacağım ve basitliği ve erişilebilirliği nedeniyle bir Linux işletim sistemine göre bir dosya kavramını kullanacağım.

Dosya nedir?

Dosya bir soyutlamadır :)

Ya da basitçe açıklayabildiğim gibi, bir dosya, dosyayı tanımlayan bir parça veri yapısı ve gerçek içerik olan bir parça verileridir.

Veri yapısı bölümü (UNIX / linux sistemlerinde inode olarak adlandırılır), içerikle ilgili önemli bilgi parçalarını tanımlar, ancak içeriğin kendisini (veya bu konuyla ilgili dosyanın adını) içermez. Sakladığı bilgi parçalarından biri, içeriğin başladığı yerin hafıza adresidir. Yani bir dosya adı (veya linux'ta bir sabit bağlantı), bir dosya tanımlayıcısı (işletim sisteminin önemsediği sayısal bir dosya adı) ve bellekte bir başlangıç ​​konumu ile dosya olarak adlandırabileceğimiz bir şeye sahibiz.

(Ana paket, işletim sistemi tarafından tanımlanan bir 'dosya'dır, çünkü nihayetinde onunla uğraşması gereken işletim sistemidir ve evet, dosyalar çok daha karmaşıktır).

Çok uzak çok iyi. Ama dosyanın içeriğini nasıl elde ederiz, sevgilinize bir aşk mektubu söyleyin, böylece yazdırabiliriz?

Bir dosyayı okumak

Sonuçtan başlayıp geriye gidersek, bilgisayarımızda bir dosya açtığımızda tüm içeriği okuyabilmemiz için ekranımıza sıçradı. Ama nasıl? Cevap çok metodik bir şekilde. Dosyanın içeriği başka bir veri yapısıdır. Bir karakter dizisi varsayalım. Bunu bir dizi olarak da düşünebiliriz.

Peki bu dizeyi nasıl 'okuruz'? Hafızadaki yerini bularak ve karakter dizimiz aracılığıyla yineleyerek, dosya sonuna ulaşana kadar her seferinde bir karakter. Başka bir deyişle bir program.

Bir dere, program çağrıldığında 'yarattı' ve hafıza konumunu sahiptir eklemek veya bağlanmak . Su hortumu örneğimize çok benzer şekilde, hortum musluğa bağlı değilse etkisizdir. Akış durumunda, var olması için bir dosyaya bağlanması gerekir.

Akışlar, örneğin girdiyi almak için bir akış veya bir dosya içeriğini standart çıktıya göndermek için bir akış gibi daha da rafine edilebilir. UNIX / linux, bizim için bat, stdin (standart giriş), stdout (standart çıkış) ve stderr (standart hata) dışında 3 dosya akışını bağlar ve açık tutar. Akışlar, veri yapılarının kendileri veya akışları açma, akışı kapatma veya bir akışın bağlı olduğu dosyayı kontrol etme hatası gibi daha karmaşık veri akışı işlemlerini gerçekleştirmemize izin veren nesneler olarak oluşturulabilir. C ++ 'lar cinbir akım nesnesi örneğidir.

Elbette, eğer seçerseniz, kendi akışınızı yazabilirsiniz.

Tanım

Akış, veriler üzerinde gerçekleştirilecek yararlı işlemler sağlarken, verilerle uğraşmanın karmaşıklığını da özetleyen, yeniden kullanılabilir bir kod parçasıdır.


Yani bir akış, verilerin içinden aktığı ortamdır. Verinin kaynağına bağlanması gerekir ve kendisi ve içinden geçen veriler üzerinde işlem yapabilir.
KingBryan

Evet. Ek bir cevap yazmak için tek nedenim, bir akışın içinden veri akışı olmasa bile var olabileceğini açıklığa kavuşturmaktı. oysa bir IRL akarsu (su ve benzeri ile) su akışı durduğunda akıntı olmaktan çıkar ve analoji hakkında düşünürken kafa karışıklığına neden olabilir.
rekurzion

1
Şu anda Java öğreniyorum ve cevabınız kafamı toplamama yardımcı oldu.
KingBryan

6

Yukarıda bahsedilen şeylere ek olarak, farklı türde akışlar vardır - Scheme veya Haskell gibi işlevsel programlama dillerinde tanımlandığı gibi - bazı işlevler tarafından isteğe bağlı olarak üretilen muhtemelen sonsuz bir veri yapısı.


6

Başka bir benzetme: Bir akışa karşı yüzemezsiniz, bu yüzden zaten okunan veriler silinirken akıştan bir sonraki bit, baytı, dizeyi veya nesneyi alabilirsiniz. Tek yön bilet ... veya temelde kalıcılığı depolamadan sadece bir kuyruk .

Öyleyse kuyruklara ihtiyacımız var mı? Sen karar ver.


bu, bir akarsuda ileri gitmeniz gerektiği anlamına gelir, geriye doğru hareket edemezsiniz. Ek olarak, hafızayı koruyan ilerledikçe önceki veriler silinir mi? Doğru
Muhammad Faizan Khan

5

"Akış" kelimesi, (gerçek hayatta) onu kullandığımızda iletmek istediğimiz şeye çok benzer bir anlamı temsil ettiği için seçilmiştir.

Bir su akışı analojisini düşünmeye başlayın. Tıpkı bir nehirdeki suyun sürekli akması gibi, sürekli bir veri akışı alırsınız. Verilerin nereden geldiğini tam olarak bilmiyorsunuz ve çoğu zaman buna ihtiyacınız yok; bir dosyadan, bir soketten veya başka bir kaynaktan olsun, gerçekten önemli değildir (olmamalıdır). Bu, bir su akışı almaya çok benzer, bu nedenle nereden geldiğini bilmenize gerek kalmaz; bir gölden, bir çeşmeden veya başka bir kaynaktan olsun, gerçekten önemli değil (olmamalı). kaynak

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.