1. Veri akışları
Nadiren bir program kendi başına bir ada olarak var olur. Programlar genellikle bir şekilde "dış dünya" ile etkileşime girer. Bu, klavyeden veri okuyarak, mesaj göndererek, İnternet'ten sayfa indirerek veya tersine uzak bir sunucuya dosya yükleyerek olabilir.
Tüm bu davranışları tek kelime ile ifade edebiliriz: Program ile dış dünya arasındaki veri alışverişi . Bekle, bu sadece bir kelime değil.
Elbette, veri alışverişinin kendisi iki kısma ayrılabilir: veri alma ve veri gönderme. Örneğin, bir nesneyi kullanarak klavyeden veri okuyorsunuz Scanner- bu veri alıyor. Ve bir komut kullanarak verileri ekranda görüntülersiniz System.out.println()— bu, veri göndermektir.
Programlamada, veri alışverişini tanımlamak için "akım" terimi kullanılır. Bu terim nereden geldi?
Gerçek hayatta, bir su akışına veya bir bilinç akışına sahip olabilirsiniz. Programlamada, veri akışlarımız var .
Akışlar çok yönlü bir araçtır. Programın herhangi bir yerden veri almasına (giriş akışları) ve herhangi bir yere veri göndermesine (çıkış akışları) izin verirler. Böylece, iki tür vardır:
- Bir giriş akışı veri almak içindir
- Çıkış akışı veri göndermek içindir
Akışları "somut" hale getirmek için Java'nın yaratıcıları iki sınıf yazdı: InputStreamve OutputStream.
Sınıfın, ondan veri okumanıza izin veren InputStreambir yöntemi vardır . read()Ve sınıfın , ona veri yazmanıza izin veren OutputStreambir yöntemi vardır . write()Başka yöntemleri de var, ama daha sonraları.
Bayt akışları
Ne tür verilerden bahsediyoruz? Hangi formatı alıyor? Başka bir deyişle, bu sınıflar hangi veri türlerini destekliyor?
Bunlar genel sınıflardır, dolayısıyla en yaygın veri türü olan byte. Bir OutputStreambayt (ve bayt dizileri) yazabilir ve bir InputStreamnesne baytları (veya bayt dizilerini) okuyabilir. İşte bu - başka veri türlerini desteklemiyorlar.
Sonuç olarak, bu akışlara bayt akışları da denir .
Akışların bir özelliği, verilerinin yalnızca sıralı olarak okunabilmesi (veya yazılabilmesidir). Önüne gelen tüm verileri okumadan akışın ortasındaki verileri okuyamazsınız.
Sınıf boyunca klavyeden veri okuma şu şekilde çalışır Scanner: klavyeden verileri sırayla, satır satır okursunuz. Bir satırı, ardından bir sonraki satırı, ardından bir sonraki satırı vb. okuruz. Uygun olarak, satırları okuma yöntemi denir nextLine().
Bir'e veri yazmak OutputStreamda sıralı olarak gerçekleşir. Bunun güzel bir örneği konsol çıktısıdır. Bir satırın çıktısını alırsınız, ardından bir başkası ve bir başkası gelir. Bu sıralı çıktıdır. İlk satırın, ardından onuncu ve ardından ikinci satırın çıktısını alamazsınız. Tüm veriler bir çıkış akışına yalnızca sıralı olarak yazılır.
Karakter akışları
Kısa bir süre önce dizelerin en popüler ikinci veri türü olduğunu öğrendiniz ve gerçekten öyleler. Karakterler ve tüm diziler şeklinde pek çok bilgi aktarılır. Bir bilgisayar, her şeyi bayt olarak gönderip almakta mükemmeldir, ancak insanlar o kadar da mükemmel değildir.
Bu gerçeği hesaba katarak, Java programcıları iki sınıf daha yazdı: Readerve Writer. Sınıf , sınıfa Readerbenzer InputStream, ancak yöntemi read()baytları değil karakterleri ( char) okur. Sınıf Writer, sınıfa karşılık gelir OutputStream. Ve tıpkı sınıf gibi , baytlarla değil Readerkarakterlerle ( ) çalışır .char
Bu dört sınıfı karşılaştırırsak, aşağıdaki resmi elde ederiz:
| Bayt (bayt) | Karakterler (karakter) | |
|---|---|---|
| veri okuma |
|
|
| veri yazma |
|
|
Pratik uygulama
, , ve sınıfların kendileri, InputStreamverilerin okunabileceği (veya verilerin yazılabileceği) herhangi bir somut nesneyle ilişkilendirilmediğinden, doğrudan kimse tarafından kullanılmaz. Ancak bu dört sınıf, çok şey yapabilen çok sayıda alt sınıfa sahiptir.OutputStreamReaderWriter
2. InputStreamsınıf
Sınıf InputStreamilginçtir çünkü yüzlerce alt sınıf için üst sınıftır. Kendine ait herhangi bir verisi yoktur, ancak tüm türetilmiş sınıflarının miras aldığı yöntemleri vardır.
Genel olarak, akış nesnelerinin verileri dahili olarak depolaması nadirdir. Akış, verileri okumak/yazmak için bir araçtır, ancak depolama değildir. Bununla birlikte, istisnalar var.
InputStreamSınıfın ve onun soyundan gelen tüm sınıfların yöntemleri :
| Yöntemler | Tanım |
|---|---|
|
Akıştan bir bayt okur |
|
Akıştan bir dizi bayt okur |
|
Akıştan tüm baytları okur |
|
nAkıştaki baytları atlar (onları okur ve atar) |
|
Akışta kaç bayt kaldığını kontrol eder |
|
Akışı kapatır |
Bu yöntemleri kısaca inceleyelim:
read()yöntem
Yöntem , akıştan bir baytread() okur ve onu döndürür. Dönüş türüyle kafanız karışmış olabilir . Bu tür, standart tamsayı türü olduğu için seçildi . öğesinin ilk üç baytı sıfır olacaktır.intintint
read(byte[] buffer)yöntem
Bu, yöntemin ikinci çeşididir read(). InputStreamBir kerede bir bayt dizisini okumanıza izin verir . Baytları saklayacak dizi bir argüman olarak iletilmelidir. Yöntem bir sayı döndürür - gerçekte okunan bayt sayısı.
Diyelim ki 10 kilobaytlık bir arabelleğiniz var ve sınıfı kullanarak bir dosyadan veri okuyorsunuz FileInputStream. Dosya yalnızca 2 kilobayt içeriyorsa, tüm veriler arabellek dizisine yüklenir ve yöntem 2048 (2 kilobayt) sayısını döndürür.
readAllBytes()yöntem
Çok iyi bir yöntem. Yalnızca bitene kadar tüm verileri okur InputStreamve tek bir bayt dizisi olarak döndürür. Bu, küçük dosyaları okumak için çok kullanışlıdır. Büyük dosyalar fiziksel olarak belleğe sığmayabilir ve yöntem bir istisna oluşturur.
skip(long n)yöntem
Bu yöntem, nesneden ilk n baytı atlamanıza izin verir InputStream. Veriler kesinlikle sırayla okunduğundan, bu yöntem yalnızca akıştan ilk n baytı okur ve onları atar.
Gerçekte atlanan bayt sayısını döndürür (baytlar atlanmadan akışın sona ermesi durumunda n).
int available()yöntem
Yöntem, akışta kalan bayt sayısını döndürür.
void close()yöntem
Yöntem close(), veri akışını kapatır ve onunla ilişkili harici kaynakları serbest bırakır. Bir akış kapatıldığında, ondan daha fazla veri okunamaz.
Çok büyük bir dosyayı kopyalayan bir örnek program yazalım. readAllBytes()Tüm dosyayı belleğe okumak için yöntemi kullanamayız . Örnek:
| kod | Not |
|---|---|
|
InputStreamdosyadan okumak için dosyaya OutputStreamyazmak için İçine verileri okuyacağımız arabellek Akışta veri olduğu sürece verileri arabelleğe oku Verileri arabellekten ikinci akışa yaz |
Bu örnekte, iki sınıf kullandık: bir dosyadan veri okumak için FileInputStreambir alt sınıf ve bir dosyaya veri yazmak için bir alt sınıf . İkinci ders hakkında biraz sonra konuşacağız.InputStreamFileOutputStreamOutputStream
Burada bir başka ilginç nokta da değişkendir real. Bir dosyadan son veri bloğu okunduğunda, kolayca 64 KB'den daha az veriye sahip olabilir. Buna göre, tamponun tamamını değil, sadece bir kısmını - ilk realbaytları - çıkarmamız gerekiyor. Bu tam olarak yöntemde olan şeydir write().
3. Readersınıf
Sınıf Reader, sınıfın tam bir analoğudur InputStream. charTek fark baytlarla değil karakterlerle ( ) çalışmasıdır . Tıpkı InputStreamsınıf gibi, Readersınıf da kendi başına hiçbir yerde kullanılmaz: yüzlerce alt sınıf için üst sınıftır ve hepsi için ortak yöntemler tanımlar.
Sınıfın yöntemleri Reader(ve onun soyundan gelen tüm sınıflar):
| Yöntemler | Tanım |
|---|---|
|
charAkıştan birini okur |
|
charAkıştan bir dizi okur |
|
n charsAkışta atlar (onları okur ve atar) |
|
Akışta kalan bir şey olup olmadığını kontrol eder |
|
Akışı kapatır |
InputStreamYöntemler, küçük farklılıklar olsa da, sınıfın yöntemlerine çok benzer .
int read()yöntem
Bu yöntem charakıştan birini okur ve onu döndürür. Tür charan olarak genişler int, ancak sonucun ilk iki baytı her zaman sıfırdır.
int read(char[] buffer)yöntem
Bu, yöntemin ikinci çeşididir read(). ReaderBir kerede hepsinden bir char dizisini okumanıza izin verir . Karakterleri saklayacak dizi argüman olarak iletilmelidir. Yöntem bir sayı döndürür - gerçekte okunan karakter sayısı.
skip(long n)yöntem
Bu yöntem, nesneden ilk n karakteri atlamanıza izin verir Reader. Sınıfın benzer yöntemiyle tamamen aynı şekilde çalışır InputStream. Gerçekte atlanan karakter sayısını döndürür.
boolean ready()yöntem
trueAkışta okunmamış bayt olup olmadığını döndürür .
void close()yöntem
Yöntem close(), veri akışını kapatır ve onunla ilişkili harici kaynakları serbest bırakır. Bir akış kapatıldığında, ondan daha fazla veri okunamaz.
Karşılaştırma için, bir metin dosyasını kopyalayan bir program yazalım:
| kod | Not |
|---|---|
|
Readerbir dosyadan okumak Writeriçin bir dosyaya yazmak için İçine verileri okuyacağımız arabellek Akışta veri olduğu sürece verileri bir arabelleğe oku Verileri arabellekten ikinci akışa yaz |
GO TO FULL VERSION