JavaRush /בלוג Java /Random-HE /קריאה מהמקלדת - "קוראים"

קריאה מהמקלדת - "קוראים"

פורסם בקבוצה
שלום! בהרצאות ובמשימות למדנו איך להוציא נתונים לקונסולה, ולהיפך – לקרוא נתונים מהמקלדת. קריאה מהמקלדת - "קוראים" - 1אפילו למדת להשתמש בבנייה מורכבת בשביל זה:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
אבל עדיין לא ענינו על שאלה אחת.

איך זה בכלל עובד?

למעשה, כל תוכנית לרוב אינה קיימת בפני עצמה. זה יכול לתקשר עם תוכניות אחרות, מערכות, אינטרנט וכו'. במילה "לתקשר" אנחנו קודם כל מתכוונים ל"החלפת נתונים". כלומר, קבל קצת נתונים מבחוץ, ולהיפך, שלח את הנתונים שלך לאנשהו. ישנן דוגמאות רבות לחילופי נתונים בין תוכניות, אפילו בחיי היומיום. לכן, באתרים רבים, במקום להירשם, אתה יכול להיכנס באמצעות חשבון הפייסבוק או הטוויטר שלך. במצב זה, שתי תוכנות, נניח, טוויטר והאתר בו אתם מנסים להירשם, מחליפות ביניהן את הנתונים הדרושים, ולאחר מכן רואים את התוצאה הסופית - הרשאה מוצלחת. המונח " זרימה " משמש לעתים קרובות לתיאור תהליך חילופי הנתונים בתכנות . מאיפה השם הזה בכלל הגיע? "זרימה" קשורה יותר לנהר או לנחל מאשר לתכנות. למעשה, זה לא בלי סיבה :) זרם הוא, במהותו, פיסת נתונים נעים. כלומר, בתכנות, לא מים "זורמים" לאורך הנחל, אלא נתונים בצורת בתים ותווים. מזרם נתונים, אנחנו יכולים לקבל נתונים בחלקים ולעשות איתם משהו. שוב, בואו נשתמש באנלוגיה של "זורמים מים": אפשר לגרוף מים מנהר כדי לבשל מרק, לכבות אש או להשקות פרחים. באמצעות זרמים, אתה יכול לעבוד עם כל מקור נתונים: האינטרנט, מערכת הקבצים של המחשב שלך או משהו אחר - זה לא משנה. זרמים הם כלי אוניברסלי. הם מאפשרים לתוכנית לקבל נתונים מכל מקום (זרמים נכנסים) ולשלוח אותם לכל מקום (זרמים יוצאים). המשימה שלהם היא אחת - לקחת נתונים במקום אחד ולשלוח אותם למקום אחר. הזרמים מתחלקים לשני סוגים:
  1. זרם נכנס ( קלט ) - משמש לקבלת נתונים
  2. זרם יוצא ( Output ) - לשליחת נתונים.
זרימת הנתונים הנכנסים ב-Java מיושמת במחלקה InputStream, ותזרים הנתונים היוצאים במחלקה OutputStream. אבל יש דרך אחרת לחלק חוטים. הם מחולקים לא רק לכניסות ויוצאות, אלא גם לבייטים ותווים . כאן המשמעות ברורה ללא הסבר: זרם בתים מעביר מידע בצורה של קבוצה של בתים, וזרם תווים מעביר מידע בצורה של קבוצה של תווים. בהרצאה זו נפרט על זרמים נכנסים. ואני אצרף מידע על קישורים יוצאים בסוף, ואתה יכול לקרוא על זה בעצמך :) אז, הקוד שלנו:
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
בטח חשבתם בזמן קריאת ההרצאות שזה נראה די מפחיד? :) אבל זה רק עד שנבין איך הדבר הזה עובד. בוא נתקן את זה עכשיו! נתחיל מהסוף. System.inהוא אובייקט של הכיתה InputStreamשדיברנו עליה בהתחלה. זהו זרם נכנס, והוא קשור להתקן הקלט של המערכת - המקלדת. אגב, אתה מכיר אותו בעקיפין. אחרי הכל, אתה משתמש לעתים קרובות ב"עמית" שלו בעבודתך - System.out! System.out- זהו זרם פלט של נתוני מערכת , הוא משמש לפלט לקונסולה בדיוק בשיטה System.out.println()שבה אתה משתמש כל הזמן :) System.out- זרם לשליחת נתונים לקונסולה, וכן System.in- לקבלת נתונים מהמקלדת. זה פשוט :) יתר על כן: כדי לקרוא נתונים מהמקלדת, אנחנו יכולים להסתדר בלי המבנה הגדול הזה ופשוט לכתוב: System.in.read();
public class Main {

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

       while (true) {
           int x = System.in.read();
           System.out.println(x);
       }
   }
}
במחלקה InputStreamSystem.in, להזכירכם, הוא אובייקט של המחלקה InputStream) ישנה שיטה read()שמאפשרת לקרוא נתונים. בעיה אחת: הוא קורא בתים , לא תווים . בואו ננסה לקרוא את האות הרוסית "יה" מהמקלדת. פלט מסוף:
Я
208
175
10
אותיות רוסיות תופסות 2 בתים בזיכרון המחשב (בניגוד לאותיות באנגלית, שתופסות רק 1). במקרה זה, 3 בתים נקראו מהזרם: השניים הראשונים מייצגים את האות "I", והשני הוא מעבר השורה (Enter). לכן, האפשרות להשתמש ב"עירום" System.inלא תתאים לנו. בני אדם (למעט חריגים נדירים!) אינם יכולים לקרוא בתים. כאן בא השיעור הבא לעזרתנו - InputStreamReader! בואו נבין איזו חיה זו.
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
אנחנו מעבירים את הנחל System.inל- InputStreamReader. באופן כללי, אם אתה מתרגם את שמו לרוסית, הכל נראה ברור - "קורא זרמים נכנסים". למעשה, בדיוק בשביל זה זה נועד! אנו יוצרים אובייקט מחלקה InputStreamReaderומעבירים לו זרם נכנס ממנו הוא אמור לקרוא נתונים. במקרה הזה...
new InputStreamReader(System.in)
...אנחנו אומרים לו: "תקרא נתונים מזרם הקלט של המערכת (מקלדת)." אבל זה לא תפקידו היחיד! InputStreamReaderלא רק מקבל נתונים מהזרם. זה גם ממיר זרמי בתים לזרמי תווים . במילים אחרות, אתה כבר לא צריך לדאוג לגבי תרגום נתוני הקריאה משפת "מחשב" לשפה "אנושית" - InputStreamReaderזה יעשה הכל בשבילך. InputStreamReader, כמובן, יכול לקרוא נתונים לא רק מהקונסולה, אלא גם ממקומות אחרים. לדוגמה, מהקובץ:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

   public static void main(String[] args) throws IOException {
       InputStreamReader inputStreamReader = new InputStreamReader(new FileInputStream("C:\\Users\\username\\Desktop\\testFile.txt"));
   }
}
כאן יצרנו זרם נתונים נכנס FileInputStream(זהו אחד הזנים InputStream), העברנו את הנתיב לקובץ לתוכו, והעברנו את הזרם עצמו InputStreamReader'y. כעת הוא יוכל לקרוא נתונים מהקובץ הזה, אם הקובץ בנתיב הזה קיים, כמובן. כדי לקרוא נתונים (לא משנה מאיפה, מהמסוף, מקובץ או מכל מקום אחר), הכיתה InputStreamReaderמשתמשת גם ב- read(). מה ההבדל בין System.in.read()לבין InputStreamReader.read()? בואו ננסה לספור את אותה האות "אני" באמצעות InputStreamReader. תן לי להזכיר לך, זה מה שחשבתי System.in.read():
Я
208
175
10
איך הוא יכול לעשות את אותה עבודה 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);
       }
   }
}
פלט מסוף:
Я
1071
10
ההבדל נראה מיד. הבת האחרון - עבור מעברי שורה - נותר ללא שינוי (המספר 10), אך האות הקריאה "I" הומרה לקוד יחיד "1071". זו קריאה לפי סמלים! אם אתה פתאום לא מאמין שקוד 1071 פירושו האות "אני", קל לאמת זאת :)
import java.io.IOException;

public class Main {

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

       char x = 1071;
       System.out.println(x);
   }
}
פלט מסוף:

Я
אבל אם InputStreamReaderזה כל כך טוב, למה אתה צריך יותר BufferedReader? InputStreamReaderיכולים גם לקרוא נתונים וגם להמיר בתים לתווים - מה עוד אנחנו צריכים? למה עוד קורא? :/ התשובה פשוטה מאוד - לפרודוקטיביות רבה יותר ולנוחות רבה יותר . בואו נתחיל עם ביצועים. בעת קריאת נתונים, BufferedReader משתמש באזור מיוחד - מאגר, שבו הוא "מוסיף" את תווי הקריאה. כתוצאה מכך, כאשר אנו צריכים את התווים הללו בתוכנית, הם יילקחו מהמאגר, ולא ישירות ממקור הנתונים (מקלדת, קובץ וכו'), וזה חוסך משאבים רבים. כדי להבין איך זה עובד, דמיינו, למשל, עבודה של שליח בחברה גדולה. השליח יושב במשרד וממתין להבאת חבילות אליו למשלוח. בכל פעם שהוא מקבל חבילה חדשה, הוא יכול מיד לצאת לדרך. אבל יכול להיות שיהיו הרבה חבילות במהלך היום, והוא יצטרך לנסוע בכל פעם בין המשרד לכתובות. במקום זאת, השליח הניח ארגז במשרד שבו כל אחד יכול לשים את החבילות שלו. עכשיו השליח יכול לקחת את הקופסה ברוגע וללכת לכתובות - הוא יחסוך הרבה זמן, כי הוא לא יצטרך לחזור כל פעם למשרד. התיבה בדוגמה זו היא בדיוק המאגר, והמשרד הוא מקור הנתונים. לשליח הרבה יותר קל לקחת מכתב מקופסה משותפת בעת שליחתו מאשר ללכת כל פעם למשרד. זה גם יחסוך בגז. זה אותו דבר בתוכנית - זה הרבה פחות עתיר משאבים לקחת נתונים מהמאגר, במקום לגשת למקור הנתונים בכל פעם. לכן BufferedReader+ InputStreamReaderעובד מהר יותר מסתם InputStreamReader. סידרנו את הביצועים, אבל מה לגבי נוחות? היתרון העיקרי הוא שהוא BufferedReaderיכול לקרוא נתונים לא רק תו אחד בכל פעם (למרות read()שיש לו גם שיטה למטרה זו), אלא גם שורות שלמות! זה נעשה באמצעות 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("We read this line from the keyboard:");
       System.out.println(s);
   }
}
פלט מסוף:
JavaRush is the best site to learn Java!
Мы считали с клавиатуры эту строку:
JavaRush — лучший сайт для изучения Java!
זה שימושי במיוחד בעת קריאת כמות גדולה של נתונים. עדיין ניתן לקרוא שורה אחת או שתיים של טקסט תו אחר תו. אבל לספור "מלחמה ושלום" אות אחת בכל פעם תהיה קצת בעייתית :) עכשיו עבודת החוטים הפכה לך הרבה יותר ברורה. למחקר נוסף, הנה מקור נוסף עבורך: כאן תוכל לקרוא עוד על זרמים נכנסים ויוצאים. סקירת וידאו BufferedReaderמאחד התלמידים שלנו. כן, כן, התלמידים שלנו לא רק לומדים את עצמם, אלא גם מקליטים סרטונים חינוכיים עבור אחרים! אל תשכחו לעשות לייק ולהירשם לערוץ שלנו :)
עדיף להרגיל את עצמך לקרוא תיעוד רשמי כבר מתחילת הלימודים. זה מקור הידע העיקרי על השפה, ותמיד אפשר למצוא שם את רוב התשובות.
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION