JavaRush /Java blogi /Random-UZ /Java-da kiritish/chiqarish. FileInputStream, FileOutputSt...

Java-da kiritish/chiqarish. FileInputStream, FileOutputStream, BufferedInputStream sinflari

Guruhda nashr etilgan
Salom! Bugungi ma'ruzamizda biz Java tilidagi kirish va chiqish oqimlari yoki qisqacha Java I/O (“kirish-chiqish”) haqida suhbatni davom ettiramiz. Bu ushbu mavzu bo'yicha birinchi ma'ruza emas va oxirgisi ham bo'lmaydi :) Shunday bo'ladiki, Java tili sifatida kiritish/chiqarish bilan ishlash uchun ko'plab imkoniyatlarni taqdim etadi. Ushbu funktsiyani amalga oshiradigan juda ko'p darslar mavjud, shuning uchun biz ularni dastlab chalkashmaslik uchun bir nechta ma'ruzalarga ajratdik :) Java-da kiritish/chiqarish.  FileInputStream, FileOutputStream, BufferedInputStream sinflari - 1Oldingi ma'ruzalarda biz BufferedReader , shuningdek InputStream & OutputStream mavhum sinflari va bir nechta mavzularga to'xtalib o'tdik. avlodlari. Bugun biz 3 ta yangi sinfni ko'rib chiqamiz: FileInputStream , FileOutputStream va BufferedInputStream .

FileOutputStream klassi

FileOutputStream sinfining asosiy maqsadi faylga bayt yozishdir. Hech qanday murakkab narsa yo'q :) FileOutputStream mavhum OutputStream sinfining ilovalaridan biridir . Konstruktorda ushbu sinf ob'ektlari maqsadli faylga (baytlar yozilishi kerak bo'lgan) yo'lni yoki sinf ob'ektini oladi File. Keling, ikkala misolni ham ko'rib chiqaylik:
public class Main {

   public static void main(String[] args) throws IOException {


       File file = new File("C:\\Users\\Username\\Desktop\\test.txt");
       FileOutputStream fileOutputStream = new FileOutputStream(file);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Ob'ektni yaratishda Filebiz konstruktorda uning joylashishi kerak bo'lgan yo'lni ko'rsatdik. Uni oldindan yaratishning hojati yo'q: agar u mavjud bo'lmasa, dastur uni o'zi yaratadi. Siz qo'shimcha ob'ekt yaratmasdan qilishingiz mumkin va shunchaki manzil bilan satrni o'tkazishingiz mumkin:
public class Main {

   public static void main(String[] args) throws IOException {


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt");

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Ikkala holatda ham natija bir xil bo'ladi. Biz faylimizni ochishimiz va u erda ko'rishimiz mumkin:

Hello! Добро пожаловать на JavaRush — лучший сайт для тех, кто хочет стать программистом!
Biroq, bu erda bitta ogohlantirish bor. Yuqoridagi misoldagi kodni ketma-ket bir necha marta ishga tushirishga harakat qiling va keyin faylga qarang va savolga javob bering: unda nechta qator yozilganligini ko'rasiz? Faqat bitta. Lekin siz kodni bir necha marta ishlatdingiz. Biroq, ma'lum bo'lishicha, ma'lumotlar har safar eskilarini almashtirib, ustiga yozilgan. Agar bu bizni qoniqtirmasa va ketma-ket yozib olish kerak bo'lsa-chi? Salomimizni faylga ketma-ket uch marta yozmoqchi bo'lsak-chi? Bu erda hamma narsa oddiy. Tilning o'zi har bir holatda qanday xatti-harakatlar kerakligini bila olmasligi sababli, FileOutputStreamsiz konstruktorga qo'shimcha parametrni o'tkazishingiz mumkin - boolean append. Agar uning qiymati rost bo'lsa , ma'lumotlar faylning oxiriga yoziladi. Agar noto'g'ri bo'lsa (va standart qiymat noto'g'ri bo'lsa ), eski ma'lumotlar o'chiriladi va yangi ma'lumotlar yoziladi. O'zgartirilgan kodimizni uch marta sinab ko'raylik va ishga tushiramiz:
public class Main {

   public static void main(String[] args) throws IOException {


       FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Username\\Desktop\\test.txt", true);

       String greetings = "Hi! Welcome to JavaRush - the best site for those who want to become a programmer!\r\n";

       fileOutputStream.write(greetings.getBytes());

       fileOutputStream.close();
   }
}
Fayldagi natija:

Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Yana bir narsa! I/U sinflaridan foydalanganda ushbu xususiyatni yodda tuting. Bir paytlar mening eski ma'lumotlarim fayllardan qayerga ketganini tushunish uchun soatlab vazifalar ustida o'tirishim kerak edi :) Va, albatta, boshqa I/U sinflarida bo'lgani kabi, close().

FileInputStream klassi

Sinf FileInputStreamteskari maqsadga ega - fayldan baytlarni o'qish. Xuddi FileOutputStreammerosxo'rlar kabi OutputStream, bu sinf mavhum sinfdan kelib chiqadi InputStream. “ test.txt ” matnimizga bir necha qator matn yozamiz:

«So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters»
Java-da kiritish/chiqarish.  FileInputStream, FileOutputStream, BufferedInputStream sinflari - 2 Fayldan ma'lumotlarni o'qishni amalga oshirishda quyidagilardan foydalaniladi FileInputStream:
public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       int i;

       while((i=fileInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
Biz fayldan bir baytni o'qiymiz, o'qilgan baytlarni belgilarga aylantiramiz va ularni konsolga chiqaramiz. Va konsoldagi natija:

So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters

BufferedInputStream klassi

O'ylaymanki, oldingi ma'ruzalardan olingan bilimlarni hisobga olgan holda, sinf nima uchun kerakligini BufferedInputStreamva uning qanday afzalliklari borligini osongina ayta olasiz FileInputStream:) Biz allaqachon buferlangan oqimlar bilan uchrashganmiz, shuning uchun o'qishni davom ettirishdan oldin taxmin qilishga (yoki eslab qolishga) harakat qiling :) Buferlangan oqimlar birinchi navbatda I/U optimallashtirish uchun kerak. Fayldan o'qish kabi ma'lumotlar manbasiga kirish unumdorlikni talab qiluvchi operatsiya hisoblanadi. Va har safar bir bayt o'qish uchun faylga kirish isrofgarchilikdir. Shuning uchun BufferedInputStreamu bir vaqtning o'zida bir bayt emas, balki bloklarda ma'lumotlarni o'qiydi va ularni vaqtincha maxsus buferda saqlaydi. Bu bizga faylga kirishlar sonini kamaytirish orqali dasturning ishlashini optimallashtirish imkonini beradi. Keling, qanday ko'rinishini ko'rib chiqaylik:
public class Main {

   public static void main(String[] args) throws IOException {

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\test.txt");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream, 200);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }
   }
}
Bu erda biz ob'ekt yaratdik BufferedInputStream. U ob'ektni yoki uning vorislaridan birini kirish sifatida qabul qiladi InputStream, shuning uchun avvalgisi FileInputStreambajaradi. Qo'shimcha parametr sifatida baytlarda bufer hajmini oladi. Endi bu tufayli ma'lumotlar fayldan bir vaqtning o'zida bir bayt emas, balki bir vaqtning o'zida 200 bayt o'qiladi! Tasavvur qiling-a, biz fayllarga kirish sonini qanchalik kamaytirdik. Samaradorlikni solishtirish uchun siz bir necha megabayt hajmdagi bir nechta katta matn faylini olishingiz va uni o'qish va konsolga millisekundlarda chiqarish uchun qancha vaqt ketishini FileInputStreamva yordamida solishtirishingiz mumkin BufferedInputStream. Mana ikkala kod misoli:
public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\textBook.rtf");

       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);

       int i;

       while((i = bufferedInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}



public class Main {

   public static void main(String[] args) throws IOException {

       Date date = new Date();

       FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Username\\Desktop\\26951280.rtf");


       int i;

       while((i = fileInputStream.read())!= -1){

           System.out.print((char)i);
       }

       Date date1 = new Date();

       System.out.println((date1.getTime() - date.getTime()));
   }
}
Kompyuterimda 1,5 MB hajmdagi faylni o'qiyotganda, FileInputStreamu ishni ~3500 millisekundda bajardi, ammo bu erda BufferedInputStreamu ishni ~1700 millisekundda bajardi. Ko'rib turganingizdek, buferlangan oqim dasturning ishlashini 2 marta optimallashtirdi! :) Biz I/O sinflarini o'rganishni davom ettiramiz - keyinroq ko'rishguncha!
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION