היי! השיעור היום יחולק לשני חלקים מטעמי נוחות. נחזור על כמה נושאים ישנים שנגענו בהם בעבר, ונשקול כמה תכונות חדשות :) בואו נתחיל עם הראשון. כבר עברת שיעור כמו
כמובן,
אז מה אנחנו צריכים כדי שזה יקרה? קודם כל, אנחנו צריכים
BufferedReader
הרבה פעמים. אני מקווה שלא הספקת לשכוח את ההצהרה הזו:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
לפני קריאה נוספת, נסו לזכור על מה אחראי כל רכיב - System.in
, InputStreamReader
, - ומדוע הוא נחוץ. BufferedReader
האם זכרת? אם לא, אל דאגה. :) אם שכחתם משהו, קראו שוב את השיעור הזה
, המוקדש לשיעורי קוראים. נזכיר בקצרה מה כל אחד מהם יכול לעשות. System.in
- זהו זרם לקבלת נתונים מהמקלדת. באופן עקרוני, זה לבד יספיק כדי ליישם את ההיגיון הנדרש לקריאת טקסט. אבל, כזכור, System.in
יכול לקרוא רק בייטים, לא תווים:
public class Main {
public static void main(String[] args) throws IOException {
while (true) {
int x = System.in.read();
System.out.println(x);
}
}
}
אם נבצע את הקוד הזה ונזין את האות הקירילית "Й", הפלט יהיה:
Й
208
153
10
תווים קיריליים תופסים 2 בתים בזיכרון, והם מוצגים על המסך. המספר 10 הוא הייצוג העשרוני של תו הזנת שורה, כלומר מהקשה על Enter. קריאת בתים היא תענוג כזה, כך שהשימוש System.in
אינו נוח במיוחד. על מנת לקרוא נכון אותיות קיריליות (ואחרות), אנו משתמשים InputStreamReader
כעטיפה:
public class Main {
public static void main(String[] args) throws IOException {
InputStreamReader reader = new InputStreamReader(System.in);
while (true) {
int x = reader.read();
System.out.println(x);
}
}
}
נזין את אותה האות "Й", אך התוצאה שונה הפעם:
Й
1049
10
InputStreamReader
המיר שני בתים (208 ו-153) למספר היחיד 1049. זה מה שזה אומר לקרוא תווים. 1049 מקביל לאות הקירילית "Й". אנחנו יכולים בקלות לשכנע את עצמנו שזה נכון:
public class Main {
public static void main(String[] args) throws IOException {
char x = 1049;
System.out.println(x);
}
}
פלט מסוף:
Й
וכמו forBufferedReader
(ובאופן כללי, BufferedAnythingYouWant
), מחלקות מאגרות משמשות למיטוב ביצועים. הגישה למקור נתונים (קובץ, קונסולה, משאב אינטרנט) היא די יקרה מבחינת ביצועים. לכן, כדי לצמצם את מספר הגישות, BufferedReader
קוראים וצוברים נתונים במאגר מיוחד, ומשם אנחנו מקבלים אותם. כתוצאה מכך, מספר הפעמים שהגישה למקור הנתונים נקצץ - אולי במספר סדרי גודל! עוד אחת BufferedReader
מהתכונות והיתרון שלה על פני הרגילות InputStreamReader
היא השיטה המועילה ביותר readLine()
, שקוראת שורות שלמות של נתונים, לא מספרים בודדים. זה, כמובן, מאוד נוח כשעוסקים בטקסטים גדולים. כך נראות שורות קריאה:
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String s = reader.readLine();
System.out.println ("The user entered the following text:");
System.out.println(s);
reader.close();
}
}
BufferedReader+InputStreamReader is faster than InputStreamReader alone
The user entered the following text:
BufferedReader+InputStreamReader is faster than InputStreamReader alone

BufferedReader
הוא מאוד גמיש. אתה לא מוגבל לעבודה עם המקלדת. לדוגמה, אתה יכול לקרוא נתונים ישירות מהאינטרנט, פשוט על ידי העברת כתובת האתר הנדרשת לקורא:
public class URLReader {
public static void main(String[] args) throws Exception {
URL oracle = new URL("https://www.oracle.com/index.html");
BufferedReader in = new BufferedReader(
new InputStreamReader(oracle.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
}
}
אתה יכול לקרוא נתונים מקובץ על ידי העברת נתיב הקובץ:
public class Main {
public static void main(String[] args) throws Exception {
FileInputStream fileInputStream = new FileInputStream("testFile.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream));
String str;
while ((str = reader.readLine()) != null) {
System.out.println (str);
}
reader.close();
}
}
החלפת System.out
עכשיו בואו נסתכל על יכולת מעניינת שלא נגענו בה בעבר. כפי שאתה בוודאי זוכר, למחלקהSystem
יש שני שדות סטטיים - System.in
ו- System.out
. האחים התאומים האלה הם חפצי זרמים. System.in
הוא InputStream
. והוא . System.out
_ PrintStream
כרגע, נדבר על System.out
. אם ניכנס System
לקוד המקור של הכיתה, נראה את זה:
public final class System {
……………...
public final static PrintStream out = null;
…………
}
לפיכך, System.out
הוא פשוט משתנה סטטי רגיל שלSystem
המחלקה. אין בזה שום קסם :) out
המשתנה הוא PrintStream
הפניה. הנה שאלה מעניינת: מתי System.out.println()
מבוצע, למה בדיוק הפלט עובר לקונסולה ולא למקום אחר? והאם אפשר לשנות את זה איכשהו? לדוגמה, נניח שאנו רוצים לקרוא נתונים מהמסוף ולכתוב אותם לקובץ טקסט. האם איכשהו אפשר ליישם זאת פשוט באמצעות System.out
שיעורי קורא וכותבים נוספים במקום? אכן, זה כן :) ואנחנו יכולים לעשות את זה למרות שהמשתנה System.out
מסומן ב- final
modifier! 
PrintStream
אובייקט חדש שיחליף את הנוכחי. האובייקט הנוכחי, המוגדר במחלקה System
כברירת מחדל, אינו משרת את המטרות שלנו: הוא מצביע על המסוף. עליך ליצור קובץ חדש שמצביע על קובץ טקסט - "היעד" לנתונים שלנו. שנית, עלינו להבין כיצד להקצות ערך חדש למשתנה System.out
. אתה לא יכול להשתמש באופרטור הקצאה פשוט, מכיוון שהמשתנה מסומן final
. בוא נעבוד אחורה מהסוף. כפי שזה קורה, System
למחלקה יש את השיטה שאנו צריכים: setOut()
. זה לוקח PrintStream
אובייקט ומגדיר אותו כיעד לפלט. זה בדיוק מה שאנחנו צריכים! כל מה שנותר הוא ליצור PrintStream
אובייקט. זה גם קל:
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
הקוד המלא ייראה כך:
public class SystemRedirectService {
public static void main(String arr[]) throws FileNotFoundException
{
PrintStream filePrintStream = new PrintStream(new File("C:\\Users\\Username\\Desktop\\test.txt"));
/* Save the current value of System.out in a separate variable so that later
we can switch back to console output */
PrintStream console = System.out;
// Assign a new value to System.out
System.setOut(filePrintStream);
System.out.println("This line will be written to the text file");
// Restore the old value of System.out
System.setOut(console);
System.out.println("But this line will be output to the console!");
}
}
כתוצאה מכך, המחרוזת הראשונה נכתבת לקובץ הטקסט, והשנייה מוצגת בקונסולה :) אתה יכול להעתיק את הקוד הזה ל-IDE שלך ולהפעיל אותו. פתחו את קובץ הטקסט ותראו שהמחרוזת נכתבה שם בהצלחה :) בכך, השיעור שלנו הגיע לסיומו. היום נזכרנו איך עובדים עם זרמים וקוראים. זכרנו איך הם שונים זה מזה ולמדנו על כמה יכולות חדשות של System.out
, שבהן השתמשנו כמעט בכל שיעור :) עד לשיעורים הבאים!
קריאה נוספת: |
---|
GO TO FULL VERSION