Salam! Bugünkü mühazirəmizdə biz Java-da giriş və çıxış axınları və ya qısaca Java I/O (“giriş-çıxış”) haqqında söhbətə davam edəcəyik. Bu, bu mövzuda ilk mühazirə deyil və sonuncu da olmayacaq :) Elə olur ki, Java bir dil olaraq giriş/çıxışla işləmək üçün bir çox imkanlar təqdim edir. Bu funksionallığı həyata keçirən kifayət qədər çox dərs var, ona görə də biz onları bir neçə mühazirəyə ayırdıq ki, əvvəlcə çaşqınlıq olmasın :) Əvvəlki mühazirələrdə BufferedReader , həmçinin InputStream & OutputStream və bir neçə mücərrəd dərslərə toxunmuşduq. nəvələri. Bu gün biz 3 yeni sinfə baxacağıq: FileInputStream , FileOutputStream və BufferedInputStream .
FileOutputStream sinfi
FileOutputStream sinifinin əsas məqsədi fayla bayt yazmaqdır. Mürəkkəb bir şey yoxdur :) FileOutputStream mücərrəd OutputStream sinifinin tətbiqlərindən biridir . Konstruktorda bu sinfin obyektləri ya hədəf fayla (baytların yazılması lazım olan) yolu, ya da sinfin obyektini götürürFile
. Hər iki nümunəyə baxaq:
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();
}
}
Obyekt yaradarkən File
konstruktorda onun yerləşəcəyi yolu göstərdik. Əvvəlcədən yaratmağa ehtiyac yoxdur: əgər o yoxdursa, proqram onu özü yaradacaq. Əlavə bir obyekt yaratmadan edə bilərsiniz və sadəcə ünvanı olan bir sətir ötürə bilərsiniz:
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();
}
}
Hər iki halda nəticə eyni olacaq. Faylımızı aça və orada görə bilərik:
Hello! Добро пожаловать на JavaRush — лучший сайт для тех, кто хочет стать программистом!
Bununla belə, burada bir xəbərdarlıq var. Yuxarıdakı nümunədəki kodu ardıcıl olaraq bir neçə dəfə işlətməyə çalışın, sonra fayla baxın və suala cavab verin: orada neçə sətir yazıldığını görürsünüz? Yalnız bir. Ancaq kodu bir neçə dəfə işlətdiniz. Bununla belə, məlum olur ki, məlumatlar hər dəfə köhnələri əvəz edərək üzərinə yazılır. Bəs bununla kifayətlənməsək və ardıcıl yazıya ehtiyacımız varsa? Bir fayla ard-arda üç dəfə salamımızı yazmaq istəsək necə olar? Burada hər şey sadədir. Dilin özü hər bir halda hansı davranışa ehtiyacımız olduğunu bilə bilmədiyi üçün FileOutputStream
konstruktora əlavə parametr ötürə bilərsiniz - boolean append
. Əgər onun dəyəri doğrudursa , verilənlər faylın sonuna yazılacaq. Əgər false (və default dəyər false olarsa ), köhnə məlumatlar silinəcək və yeni məlumatlar yazılacaq. Dəyişdirilmiş kodumuzu üç dəfə sınaqdan keçirək və işlədək:
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();
}
}
Faylda nəticə:
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Başqa bir şey! I/O siniflərindən istifadə edərkən bu xüsusiyyəti yadda saxlayın. Bir vaxtlar köhnə məlumatlarımın fayllardan hara getdiyini anlamaq üçün tapşırıqların üstündə saatlarla oturmalı olurdum :) Və təbii ki, digər I/O siniflərində olduğu kimi, close()
.
FileInputStream sinfi
SinfinFileInputStream
əks məqsədi var - fayldan baytları oxumaq. FileOutputStream
Varis kimi OutputStream
, bu sinif mücərrəd sinifdən yaranır InputStream
. “ test.txt ” mətnimizə bir neçə sətir mətn yazaq:
«So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters»
Bir fayldan məlumatların oxunmasının tətbiqi budur 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);
}
}
}
Fayldan bir bayt oxuyuruq, oxunan baytları simvollara çevirib konsola çıxarırıq. Və konsolda nəticə budur:
So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters
BufferedInputStream sinfi
Düşünürəm ki, əvvəlki mühazirələrdən əldə edilən bilikləri nəzərə alaraq, sinifin nə üçün lazım olduğunuBufferedInputStream
və onun hansı üstünlüklərə malik olduğunu asanlıqla deyə bilərsiniz FileInputStream
:) Biz artıq buferli axınlarla qarşılaşmışıq, ona görə də oxumağa davam etməzdən əvvəl təxmin etməyə (və ya yadda saxlamağa) çalışın :) Buferli axınlar ilk növbədə I/O optimallaşdırmaq üçün lazımdır. Məlumat mənbəyinə daxil olmaq, məsələn, fayldan oxumaq, performans tələb edən bir əməliyyatdır. Və hər dəfə bir bayt oxumaq üçün fayla daxil olmaq israfçılıqdır. Buna görə də o, BufferedInputStream
məlumatları bir bayt deyil, bloklarda oxuyur və onları müvəqqəti olaraq xüsusi buferdə saxlayır. Bu, bizə fayla girişlərin sayını azaltmaqla proqramın işini optimallaşdırmağa imkan verir. Gəlin görək nə kimi görünür:
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);
}
}
}
Burada bir obyekt yaratdıq BufferedInputStream
. O, bir obyekti və ya onun varislərindən hər hansı birini giriş kimi qəbul edir InputStream
, buna görə də əvvəlkisi FileInputStream
edəcək. Əlavə parametr kimi baytlarda bufer ölçüsünü götürür. İndi bunun sayəsində verilənlər fayldan bir bayt deyil, bir dəfəyə 200 bayt oxunacaq! Təsəvvür edin ki, biz fayla girişlərin sayını nə qədər azaltmışıq. FileInputStream
Performansı müqayisə etmək üçün bir neçə meqabayt ölçüsündə bir neçə böyük mətn faylı götürə və onu oxumaq və və istifadə edərək millisaniyələrdə konsola çıxarmaq üçün nə qədər vaxt lazım olduğunu müqayisə edə bilərsiniz BufferedInputStream
. Budur hər iki kod nümunəsi:
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()));
}
}
Kompüterimdə 1,5 MB-lıq faylı oxuyarkən FileInputStream
o, işi ~3500 millisaniyə ərzində yerinə yetirdi, amma burada BufferedInputStream
işi ~1700 millisaniyədə etdi. Gördüyünüz kimi, buferli axın proqramın performansını 2 dəfə optimallaşdırdı! :) Biz I/O dərslərini öyrənməyə davam edəcəyik - tezliklə görüşərik!
GO TO FULL VERSION