JavaRush /בלוג Java /Random-HE /I/O ב-Java. מחלקות FileInputStream, FileOutputStream, Buf...

I/O ב-Java. מחלקות FileInputStream, FileOutputStream, BufferedInputStream

פורסם בקבוצה
שלום! בהרצאה של היום נמשיך את השיחה על זרמי קלט ופלט ב-Java, או בקיצור Java I/O ("קלט-פלט"). זו לא ההרצאה הראשונה בנושא זה, והיא לא תהיה האחרונה :) במקרה ש-Java כשפה מספקת הזדמנויות רבות לעבודה עם קלט/פלט. יש די הרבה שיעורים שמיישמים את הפונקציונליות הזו, אז חילקנו אותם לכמה הרצאות כדי שלא תתבלבלו בהתחלה :) I/O ב-Java.  מחלקות FileInputStream, FileOutputStream, BufferedInputStream - 1בהרצאות קודמות נגענו ב- BufferedReader , כמו גם במחלקות המופשטות InputStream & OutputStream ועוד כמה צאצאים. היום נסתכל על 3 מחלקות חדשות: FileInputStream , FileOutputStream ו- BufferedInputStream .

מחלקה FileOutputStream

המטרה העיקרית של המחלקה FileOutputStream היא לכתוב בתים לקובץ. שום דבר מסובך :) FileOutputStream הוא אחד המימושים של המחלקה המופשטת OutputStream . בבנאי, אובייקטים של מחלקה זו לוקחים את הנתיב לקובץ היעד (שאליו צריך לכתוב את הבייטים) או אובייקט של המחלקה File. בואו נסתכל על שתי הדוגמאות:
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();
   }
}
בעת יצירת אובייקט, Fileציינו בבנאי את הנתיב שבו הוא אמור להיות ממוקם. אין צורך ליצור אותו מראש: אם הוא לא קיים, התוכנית תיצור אותו בעצמה. אתה יכול לעשות בלי ליצור אובייקט נוסף ופשוט להעביר מחרוזת עם הכתובת:
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();
   }
}
התוצאה בשני המקרים תהיה זהה. נוכל לפתוח את הקובץ שלנו ולראות שם:

Hello! Добро пожаловать на JavaRush — лучший сайт для тех, кто хочет стать программистом!
עם זאת, יש כאן אזהרה אחת. נסה להריץ את הקוד מהדוגמה למעלה מספר פעמים ברציפות, ולאחר מכן הסתכל בקובץ וענה על השאלה: כמה שורות אתה רואה כתובים בו? רק אחד. אבל הרצת את הקוד כמה פעמים. עם זאת, מסתבר שהנתונים הוחלפו בכל פעם והחליפו את הישנים. מה אם אנחנו לא מרוצים מזה וזקוקים להקלטה ברצף? מה אם נרצה לכתוב את הברכה שלנו לקובץ שלוש פעמים ברציפות? הכל פשוט כאן. מכיוון שהשפה עצמה לא יכולה לדעת איזה סוג של התנהגות אנחנו צריכים בכל מקרה, FileOutputStreamאתה יכול להעביר פרמטר נוסף לבנאי - boolean append. אם הערך שלו נכון , הנתונים ייכתבו לסוף הקובץ. אם false (וערך ברירת המחדל הוא false ), נתונים ישנים יימחקו ונתונים חדשים ייכתבו. בוא נבדוק ונפעיל את הקוד ששונה שלוש פעמים:
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();
   }
}
תוצאה בקובץ:

Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
Hello! Добро пожаловать на JavaRush - лучший сайт для тех, кто хочет стать программистом!
עוד דבר! זכור תכונה זו בעת שימוש בשיעורי I/O. פעם, הייתי צריך לשבת שעות על משימות כדי להבין לאן הנתונים הישנים שלי הגיעו מקבצים :) וכמובן, כמו במקרה של מחלקות I/O אחרות, אל תשכח לשחרר משאבים דרך ה- close().

מחלקה FileInputStream

למחלקה יש FileInputStreamמטרה הפוכה - קריאת בתים מקובץ. בדיוק כמו FileOutputStreamירושה OutputStream, מחלקה זו נובעת מהמחלקה המופשטת InputStream. בוא נכתוב מספר שורות טקסט לתוך הטקסט שלנו " test.txt ":

«So close no matter how far
Couldn't be much more from the heart
Forever trusting who we are
And nothing else matters»
I/O ב-Java.  מחלקות FileInputStream, FileOutputStream, BufferedInputStream - 2 זה מה שהיישום של קריאת נתונים מקובץ באמצעות 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);
       }
   }
}
אנו קוראים בייט אחד מהקובץ, ממירים את הבייטים הנקראים לתווים ומוציאים אותם לקונסולה. והנה התוצאה בקונסולה:

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

מחלקה BufferedInputStream

אני חושב, בהתחשב בידע מהרצאות קודמות, אפשר לדעת בקלות למה השיעור נחוץ BufferedInputStreamומה היתרונות שיש לו על פני FileInputStream:) כבר נפגשנו עם זרמים מפוצלים, אז נסו לנחש (או לזכור) לפני המשך קריאה :) זרמים מפוצלים נחוצים בעיקר כדי לייעל את ה-I/O. גישה למקור נתונים, כגון קריאה מקובץ, היא פעולה עתירת ביצועים. והגישה לקובץ כדי לקרוא בייט אחד בכל פעם היא בזבזנית. לכן, BufferedInputStreamהוא קורא נתונים לא בייט אחד בכל פעם, אלא בבלוקים ומאחסן אותם באופן זמני במאגר מיוחד. זה מאפשר לנו לייעל את פעולת התוכנית על ידי הפחתת מספר הגישה לקובץ. בוא נראה איך זה נראה:
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);
       }
   }
}
כאן יצרנו אובייקט BufferedInputStream. הוא מקבל אובייקט או כל אחד מהממשיכים שלו כקלט InputStream, כך שהקודם FileInputStreamיעשה זאת. הוא לוקח את גודל המאגר בבתים כפרמטר נוסף. כעת, הודות לכך, הנתונים ייקראו מהקובץ לא בייט אחד בכל פעם, אלא 200 בכל פעם! תארו לעצמכם כמה צמצמנו את מספר הגישה לקבצים. כדי להשוות ביצועים, אתה יכול לקחת קובץ טקסט גדול בגודל של כמה מגה-בייט ולהשוות כמה זמן לוקח לקרוא אותו ולהוציא אותו לקונסולה באלפיות שניות באמצעות FileInputStreamו BufferedInputStream. הנה שתי הדוגמאות לקוד:
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()));
   }
}
כשקוראים קובץ של 1.5 מגה-בייט במחשב שלי, FileInputStreamהוא עשה את העבודה תוך ~3500 מילישניות, אבל כאן BufferedInputStreamהוא עשה את העבודה בתוך ~1700 מילישניות. כפי שאתה יכול לראות, הזרם המאוחסן מיטב את ביצועי התוכנית פי 2! :) נמשיך ללמוד שיעורי I/O - נתראה מאוחר יותר!
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION