Ma'lumot oqimlari

All lectures for UZ purposes
Daraja, Dars
Mavjud

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
InputStream
Reader
Ma'lumotlarni yozish
OutputStream
Writer

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
int read()
Oqimdan bitta baytni o'qiydi
int read(byte[] buffer)
Oqimdan baytlar massivini o'qiydi
byte[] readAllBytes()
Oqimdan barcha baytlarni o'qiydi
long skip(long n)
Oqimdan n baytni o'tkazib yuboradi (o'qiydi va chiqarib tashlaydi)
int available()
Oqimda yana qancha bayt qolgani tekshiriladi
void close()
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
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileInputStream input = new FileInputStream(src);
FileOutputStream output = new FileOutputStream(dest))
{
   byte[] buffer = new byte[65536]; // 64Kb
   while (input.available() > 0)
   {
      int real = input.read(buffer);
      output.write(buffer, 0, real);
   }
}



InputStream fayldan o'qish uchun
OutputStream faylga yozish uchun

Ma'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
int read()
Oqimdan bitta charni o'qiydi
int read(char[] buffer)
Oqimdan charlar massivini o'qiydi
long skip(long n)
Oqimdan n ta charni o'tkazib yuboradi (o'qiydi va chiqarib tashlaydi)
boolean ready()
Oqimda hali o'qilmagan narsa borligini tekshiradi
void close()
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
String src = "c:\\projects\\log.txt";
String dest = "c:\\projects\\copy.txt";

try(FileReader reader = new FileReader(src);
FileWriter writer = new FileWriter(dest))
{
   char[] buffer = new char[65536]; // 64Kb
   while (reader.ready())
   {
      int real = reader.read(buffer);
      writer.write(buffer, 0, real);
   }
}



Reader fayldan o'qish uchun
Writer faylga yozish uchun

Ma'lumotlar o'qiladigan bufer
Oqimda ma'lumot bo'lsa

Ma'lumotlarni buferga o'qish
Ma'lumotlarni buferdan ikkinchi oqimga yozish

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION