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ı: InputStream
ve OutputStream
.
Sınıfın, ondan veri okumanıza izin veren InputStream
bir yöntemi vardır . read()
Ve sınıfın , ona veri yazmanıza izin veren OutputStream
bir 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 OutputStream
bayt (ve bayt dizileri) yazabilir ve bir InputStream
nesne 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 OutputStream
da 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ı: Reader
ve Writer
. Sınıf , sınıfa Reader
benzer 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 Reader
karakterlerle ( ) ç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, InputStream
verilerin 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.OutputStream
Reader
Writer
2. InputStream
sınıf
Sınıf InputStream
ilginç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.
InputStream
Sı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 |
|
n Akış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.int
int
int
read(byte[] buffer)
yöntem
Bu, yöntemin ikinci çeşididir read()
. InputStream
Bir 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 InputStream
ve 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 |
---|---|
|
InputStream dosyadan okumak için dosyaya OutputStream yazmak 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 FileInputStream
bir 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.InputStream
FileOutputStream
OutputStream
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 real
baytları - çıkarmamız gerekiyor. Bu tam olarak yöntemde olan şeydir write()
.
3. Reader
sınıf
Sınıf Reader
, sınıfın tam bir analoğudur InputStream
. char
Tek fark baytlarla değil karakterlerle ( ) çalışmasıdır . Tıpkı InputStream
sınıf gibi, Reader
sı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 |
---|---|
|
char Akıştan birini okur |
|
char Akıştan bir dizi okur |
|
n chars Akışta atlar (onları okur ve atar) |
|
Akışta kalan bir şey olup olmadığını kontrol eder |
|
Akışı kapatır |
InputStream
Yöntemler, küçük farklılıklar olsa da, sınıfın yöntemlerine çok benzer .
int read()
yöntem
Bu yöntem char
akıştan birini okur ve onu döndürür. Tür char
an 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()
. Reader
Bir 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
true
Akış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 |
---|---|
|
Reader bir dosyadan okumak Writer iç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