1. Ma'lumot oqimlari
Har qanday dastur kamdan-kam hollarda o'zi mavjud bo'ladi. Odatda u qandaydir tarzda "tashqi dunyo" bilan o'zaro aloqada bo'ladi. Bu klaviaturadan ma'lumotlarni o'qish, xabarlar yuborish, internetdan sahifalarni yuklash yoki, aksincha, fayllarni uzoq serverga yuklash bo'lishi mumkin.
Bularning barchasini biz bir so'z bilan nomlashimiz mumkin — ma'lumot almashinuvi jarayoni dastur va tashqi dunyo o'rtasida. Garchi bu allaqachon bitta so'z emas.
Ma'lumot almashinuvi jarayonini ikkita turga ajratish mumkin: ma'lumotlarni olish va ma'lumotlarni yuborish. Masalan, siz Scanner obyekti bilan klaviaturadan ma'lumotlarni o'qiyapsiz - bu ma'lumotlarni olish. Va System.out.println() buyrug'i bilan ma'lumotlarni ekranga chiqarasiz - bu ma'lumotlarni yuborish.
Dasturlashda ma'lumot almashinuvi jarayonini tasvirlash uchun oqim atamasi ishlatiladi. Umuman olganda bunday nom qayerdan keldi?
Haqiqiy hayotda bu suv oqimi yoki odamlar oqimi (odamlar oqimi) bo'lishi mumkin. Dasturlashda esa oqim ma'lumot oqimi ni anglatadi.
Oqimlar universal vositadir. Ular dasturga ma'lumotlarni istalgan joydan olish imkonini beradi (kiruvchi oqimlar) va ma'lumotlarni istalgan joyga jo'natadi (chiquvchi oqimlar). Ular ikki turga bo'linadi:
- Kirish oqimi (Input): ma'lumotlarni olish uchun ishlatiladi
- Chiqish oqimi (Output): ma'lumotlarni yuborish uchun ishlatiladi
Oqimlarni "qo'l bilan ushlab ko'rish" mumkin bo'lishi uchun Java ishlab chiquvchilari ikkita sinf yozdilar: InputStream va OutputStream.
InputStream sinfida read() metodi mavjud bo'lib, undan ma'lumotlarni o'qish imkonini beradi. Va OutputStream sinfida write() metodi mavjud bo'lib, unga ma'lumotlarni yozish imkonini beradi. Ularda boshqa metodlar ham bor, lekin bu haqda keyinroq.
Baytli oqimlar
Aks holda, bular nima ma'lumotlar va ular qanday shaklda o'qilishi mumkin? Boshqacha aytganda, bu sinflar qanday ma'lumot turlarini qo'llab-quvvatlaydi?
Oh, bular universal sinflar va shuning uchun ular eng ko'p tarqalgan ma'lumot turini qo'llab-quvvatlaydi - byte. OutputStreamga baytlarni (va baytlar massivlarini) yozish mumkin, va InputStream obyektdan baytlarni (yoki baytlar massivlarini) o'qish mumkin. Barchasi — boshqa ma'lumot turlarini ular qo'llab-quvvatlamaydi.
Shu sababli bunday oqimlar ham baytli oqimlar deb ataladi.
Oqimlarning xususiyati shundaki, ulardan ma'lumotlarni faqat ketma-ketlikda o'qish (yozish) mumkin. Oqimning o'rtasidan ma'lumotlarni oldindan o'qimasdan o'qish mumkin emas.
Aynan Scanner sinfi orqali klaviaturadan o'qish xuddi shunday ishlaydi: siz klaviaturadan ma'lumotlarni ketma-ketlikda o'qiysiz: qator ketidan qator. Bir qator o'qildi, keyingi qator o'qildi, keyingi qator o'qildi va hokazo. Shu sababli qatordan o'qish metodi nextLine() deb ataladi (so'zma-so'z — "keyingi qator").
OutputStream oqimiga ma'lumotlarni yozish ham ketma-ketlikda ro'y beradi. Yaxshi misol - ekranga chiqarish. Siz satrni chiqarasiz, undan keyin yana birini va yana birini. Bu ketma-ket chiqarish. Siz avval 1-qatorni, keyin 10-qatorni, so'ngra 2-qatorni chiqarib bo'lmaydi. Barcha ma'lumotlar faqat ketma-ketlikda chiqish oqimiga yoziladi.
Simvolli oqimlar
Yaqinda siz simvollar — eng mashhur ma'lumot turlaridan biri ekanligini o'rgandingiz va haqiqatdan ham shunday. Juda ko'p ma'lumotlar simvollar va butun qatorda uzatiladi. Kompyuter barchasini baytlar ko'rinishida uzatgan bo'lar edi, lekin odamlar unchalik mukammal emas.
Java dasturchilari bu faktni inobatga olishdi va yana ikkita sinf yozishdi: Reader va Writer. Reader sinfi — bu InputStream sinfiga o'xshash, faqat bu read() metodi baytlar emas, balki simvollar — charni o'qiydi. Writer sinfi OutputStream sinfiga mos keladi va Reader sinfi kabi simvollar (char) bilan ishlaydi, baytlar emas.
Agar bu to'rtta sinfni solishtirsak, biz bunday tasvirni olamiz:
| Baytlar (byte) | Simvollar (char) | |
|---|---|---|
| Ma'lumotlarni o'qish | |
|
| Ma'lumotlarni yozish | |
|
Amaliy qo'llanilishi
O'z-o'zidan InputStream, OutputStream, Reader va Writer sinflarini hech kim to'g'ridan-to'g'ri ishlatmaydi: ular hech qanday tashqi obyektdan ajratilgan emas, ulardan o'qish yoki ular ichiga yozish mumkin. Lekin bu to'rtta sinfning ko'pdan-ko'p avlod sinflari bor, va ular juda ko'p narsaga qodirlar.
2. InputStream sinfi
InputStream sinfi qiziqarli, chunki u yuzlab avlod sinflarining ota sinfi hisoblanadi. O'zi hech qanday ma'lumotni saqlamaydi, ammo unda barcha ularning avlod sinflarida mavjud bo'lgan metodlar mavjud.
Oqim obyektlari kamdan-kam hollarda o'zlarida ma'lumot saqlaydi. Oqim — bu ma'lumotlarni o'qish/yozish vositasi, ammo saqlash emas. Garchand, ba'zan istisnolar ham bo'ladi.
InputStream sinfining va uning barcha avlod sinflarining metodlari:
| Metodlar | Tavsif |
|---|---|
|
Oqimdan bitta baytni o'qiydi |
|
Oqimdan baytlar massivini o'qiydi |
|
Oqimdan barcha baytlarni o'qiydi |
|
Oqimdan n baytni o'tkazib yuboradi (o'qiydi va chiqarib tashlaydi) |
|
Oqimda yana qancha bayt qolgani tekshiriladi |
|
Oqimni yopadi |
Bu metodlarni qisqacha ko'rib chiqamiz:
read() metodi
read() metodi oqimdan bir baytni o'qiydi va qaytaradi. Sizni natija turi — int chalg'itishi mumkin, ammo bu shunday qilingan, chunki int turi barcha butun sonlar uchun standart. int turining uchinchi birinchi baytlari nolgadir.
read(byte[] buffer) metodi
Bu read() metodining ikkinchi modifikatsiyasi. U InputStreamdan darhol baytlar massivini o'qish imkonini beradi. Baytlarni saqlash uchun massivni parametr sifatida berish kerak. Metod raqamni qaytaradi — haqiqatan o'qilgan baytlar sonini.
Misol keltiraylik, sizda 10 kilobaytlik bufer bor va FileInputStream sinfi yordamida fayldan ma'lumotlarni o'qiyapsiz. Agar faylda faqat 2 kilobayt bo'lsa, barcha ma'lumotlar massiv buferiga joylashtiriladi va metod 2048 raqamni qaytaradi (2 kilobayt).
readAllBytes() metodi
Juda yaxshi metod. U oddiygina InputStreamdan barcha ma'lumotlarni, ular tugamaguncha, o'qiydi va ularni yagona baytlar massivi ko'rinishida qaytaradi. Kichik fayllarni o'qish uchun juda qulay. Katta fayllar jismonan xotiraga joylashmasligi mumkin va metod istisno chiqaradi.
skip(long n) metodi
Bu metod InputStream obyektdan n birinchi baytni o'tkazib yuborish imkonini beradi. Ma'lumotlar qat'iyan ketma-ketlikda o'qiladi, shuning uchun bu metod oddiygina oqimdan n birinchi baytni o'qiydi va chiqarib tashlaydi.
Haqiqatan o'tkazib yuborilgan baytlari sonini qaytaradi (agar oqim n bayt aylantirishdan oldin tugagan bo'lsa).
int available() metodi
Metod oqimda yana qancha bayt qolgani haqida ma'lumot qaytaradi
void close() metodi
close() metodi ma'lumot oqimini yopadi va u bilan bog'liq tashqi resurslarni ozod qiladi. Oqim yopilgandan so'ng, undan ma'lumotlarni o'qib bo'lmaydi.
Keling, juda katta faylni nusxa ko'chiradigan dasturiy misol yozamiz. Uni readAllBytes() metodi yordamida to'liq xotiraga o'qib bo'lmaydi. Misol:
| Kod | Izoh |
|---|---|
|
InputStream fayldan o'qish uchunOutputStream faylga yozish uchunMa'lumotlar o'qiladigan bufer Oqimda ma'lumot bo'lsa Ma'lumotlarni buferga o'qish Ma'lumotlarni buferdan ikkinchi oqimga yozish |
Bu misolda biz ikki sinfdan foydalanamiz: FileInputStream — fayldan ma'lumotlarni o'qish uchun InputStream avlodi, va FileOutputStream sinfi — faylga ma'lumotlarni yozish uchun OutputStream avlodi. Ikkinchi sinf haqida biroz keyinroq gaplashamiz.
Yana bir qiziqarli nuqta — bu real o'zgaruvchi. Faylning oxirgi ma'lumotlar bloki o'qilganda, uning uzunligi 64Kb dan kichik bo'lib qolishi mumkin. Shuning uchun outputga ham to'liq bufer emas, balki faqat bir qismi, ya'ni real baytlarni yozish kerak. Aynan bu method write()da amalga oshiriladi.
3. Reader sinfi
Reader sinfi — bu InputStream sinfining to'liq analogi, faqat bitta farqi bilan: u simvollar — char bilan ishlaydi, baytlar bilan emas. Reader sinfi, shuningdek, InputStream sinfi kabi o'zi hech qayerda ishlatilmaydi: u yuzlab avlod sinflarining ota sinfi va hammasi uchun umumiy metodlarni belgilaydi.
Reader sinfining (va uning barcha avlod sinflarining) metodlari:
| Metodlar | Tavsif |
|---|---|
|
Oqimdan bitta charni o'qiydi |
|
Oqimdan charlar massivini o'qiydi |
|
Oqimdan n ta charni o'tkazib yuboradi (o'qiydi va chiqarib tashlaydi) |
|
Oqimda hali o'qilmagan narsa borligini tekshiradi |
|
Oqimni yopadi |
Metodlar InputStream sinfi metodlariga juda o'xshash, garchi kichik farqlar ham mavjud.
int read() metodi
Bu metod oqimdan bitta charni o'qiydi va qaytaradi. char turi int turiga kengaytiriladi, ammo natijaning ikki birinchi baytlari har doim nolgadir.
int read(char[] buffer) metodi
Bu read() metodining ikkinchi modifikatsiyasi. U Readerdan darhol simvollar massivini o'qish imkonini beradi. Simvollar uchun massivni parametr sifatida berish kerak. Metod raqamni qaytaradi — haqiqatan o'qilgan simvollar sonini.
skip(long n) metodi
Bu metod Reader obyektdan n birinchi simvollarni o'tkazib yuborish imkonini beradi. InputStream sinfining shunga o'xshash metodi kabi ishlaydi. Haqiqatan o'tkazib yuborilgan simvollar sonini qaytaradi.
boolean ready() metodi
Agar oqimda hali o'qilmagan baytlar bo'lsa, trueni qaytaradi.
void close() metodi
close() metodi ma'lumot oqimini yopadi va u bilan bog'liq tashqi resurslarni ozod qiladi. Oqim yopilgandan so'ng, undan ma'lumotlarni o'qib bo'lmaydi.
Keling, taqqoslash uchun matnli faylni nusxa ko'chiradigan dastur yozamiz:
| Kod | Izoh |
|---|---|
|
Reader fayldan o'qish uchunWriter faylga yozish uchunMa'lumotlar o'qiladigan bufer Oqimda ma'lumot bo'lsa Ma'lumotlarni buferga o'qish Ma'lumotlarni buferdan ikkinchi oqimga yozish |
GO TO FULL VERSION