1 00:00:00,000 --> 00:00:02,000 [Powered by Google Translate] [קובץ I / O] 2 00:00:02,000 --> 00:00:04,000 [ג'ייסון הירשהורן, אוניברסיטת הרווארד] 3 00:00:04,000 --> 00:00:07,000 [זה CS50, CS50.TV] 4 00:00:07,000 --> 00:00:11,000 כאשר אנו חושבים על קובץ, מה שעולה על דעת הוא מסמך Microsoft Word, 5 00:00:11,000 --> 00:00:14,000 תמונת JPEG, או שיר MP3, 6 00:00:14,000 --> 00:00:17,000 והאינטראקציה שלנו עם כל אחד מסוגי קבצים אלה בדרכים שונות. 7 00:00:17,000 --> 00:00:20,000 לדוגמה, במסמך Word להוסיף טקסט 8 00:00:20,000 --> 00:00:24,000 ואילו בתמונת JPEG אנחנו עלולים לחתוך את הקצוות או לרטש את הצבעים. 9 00:00:24,000 --> 00:00:28,000 עם זאת, מתחת למכסת המנוע של כל קבצים במחשב שלנו הם לא יותר 10 00:00:28,000 --> 00:00:31,000 מרצף ארוך של אפסים ואחדים. 11 00:00:31,000 --> 00:00:33,000 זה תלוי ביישום הספציפי שמקיים אינטראקציה עם הקובץ 12 00:00:33,000 --> 00:00:38,000 כדי להחליט כיצד תהליך ארוך הרצף הזה ולהציג אותו למשתמש. 13 00:00:38,000 --> 00:00:41,000 מצד אחד, מסמך עשוי להסתכל רק בית אחד, 14 00:00:41,000 --> 00:00:45,000 או 8 אפסים ואחדים, ולהציג תו ASCII על המסך. 15 00:00:45,000 --> 00:00:48,000 מצד השני, תמונת מפה סיבית יכולה להסתכל על 3 בתים, 16 00:00:48,000 --> 00:00:50,000 או 24 אפסים ואחדים, 17 00:00:50,000 --> 00:00:53,000 ומפרש אותם כ3 מספרים הקסדצימליים 18 00:00:53,000 --> 00:00:56,000 שמייצגים את הערכים עבור אדום, ירוק וכחול 19 00:00:56,000 --> 00:00:58,000 בפיקסל אחד של תמונה. 20 00:00:58,000 --> 00:01:01,000 כל מה שהם עשויים להיראות על המסך שלך, בליבה שלהם, 21 00:01:01,000 --> 00:01:05,000 קבצים הם לא יותר מאשר רצף של אפסים ואחדים. 22 00:01:05,000 --> 00:01:08,000 אז בואו לצלול פנימה ולהסתכל על איך שאנחנו משחקים באפסים והאחדים הללו בעצם 23 00:01:08,000 --> 00:01:12,000 כשזה מגיע לכתיבה ולקריאה מקובץ. 24 00:01:12,000 --> 00:01:15,000 >> אני מתכוון להתחיל על ידי פירוקו לתהליך פשוט 3-חלק. 25 00:01:15,000 --> 00:01:19,000 בשלב בא, אני אצלול לשתי דוגמאות קוד המדגימים שלושה החלקים הללו. 26 00:01:19,000 --> 00:01:23,000 לבסוף, אני אבדוק את התהליך וחלק מהפרטים החשובים ביותר שלה. 27 00:01:23,000 --> 00:01:25,000 כמו בכל קובץ שיושב על שולחן העבודה שלך, 28 00:01:25,000 --> 00:01:28,000 הדבר הראשון שיש לעשות הוא לפתוח אותו. 29 00:01:28,000 --> 00:01:31,000 ב C אנו עושים זאת על ידי ההכרזה מצביעה ל struct מוגדר מראש 30 00:01:31,000 --> 00:01:33,000 שמייצג את קובץ בדיסק. 31 00:01:33,000 --> 00:01:38,460 בקריאה לפונקציה הזאת, אנחנו גם להחליט אם אנחנו רוצים לכתוב או לקרוא מהקובץ. 32 00:01:38,460 --> 00:01:41,660 בשלב בא, אנחנו עושים את הקריאה וכתיבה עוצמה. 33 00:01:41,660 --> 00:01:44,800 ישנן מספר הפונקציות מיוחדות שאנחנו יכולים להשתמש בחלק זה, 34 00:01:44,800 --> 00:01:48,790 וכמעט כולם מתחילים באות F, אשר עומד על קובץ. 35 00:01:48,790 --> 00:01:53,560 אחרון, בדומה לX האדום הקטן בפינה העליונה של הקבצים הפתוחים במחשב שלך, 36 00:01:53,560 --> 00:01:56,680 אנחנו סוגרים את הקובץ עם קריאה לפונקציה סופית. 37 00:01:56,680 --> 00:01:59,540 עכשיו שיש לנו מושג כללי על מה שאנחנו הולכים לעשות, 38 00:01:59,540 --> 00:02:02,000 בואו לצלול לתוך הקוד. 39 00:02:02,000 --> 00:02:06,100 >> במדריך זה, יש לנו שני קבצי C וקבצי ההפעלה המקביל שלהם. 40 00:02:06,100 --> 00:02:09,710 התכנית לוקחת מכונת כתיבת טיעון שורת פקודה אחת, 41 00:02:09,710 --> 00:02:12,060 שמו של המסמך שאנחנו רוצים ליצור. 42 00:02:12,060 --> 00:02:16,160 במקרה זה, אנחנו קוראים לזה doc.txt. 43 00:02:16,160 --> 00:02:19,080 בואו להפעיל את התכנית ולהיכנס כמה שורות. 44 00:02:19,080 --> 00:02:23,660 היי. השמי הוא ג'ייסון. 45 00:02:23,660 --> 00:02:26,710 לבסוף, אנו מקלידים "התפטרנו". 46 00:02:26,710 --> 00:02:29,720 אם עכשיו רשימה של כל קבצים בספרייה זו, 47 00:02:29,720 --> 00:02:33,770 אנו רואים כי קיים מסמך חדש נקרא doc.txt. 48 00:02:34,190 --> 00:02:36,110 זה הקובץ זה עתה יצר תכנית. 49 00:02:36,110 --> 00:02:40,520 וכמובן, גם היא לא יותר מאשר רצף ארוך של אפסים ואחדים. 50 00:02:41,100 --> 00:02:43,260 אם נפתח הקובץ החדש הזה, 51 00:02:43,260 --> 00:02:45,870 אנו רואים את 3 שורות של קוד שנכנסנו לתכנית שלנו - 52 00:02:46,060 --> 00:02:49,060 היי. שם מאי הוא ג'ייסון. 53 00:02:49,580 --> 00:02:52,090 אך מה שבאמת קורה כאשר typewriter.c פועל? 54 00:02:52,810 --> 00:02:55,520 השורה הראשונה של ריבית עבורנו היא 24 קו. 55 00:02:55,560 --> 00:02:58,490 בקו הזה, אנו מצהירים מצביע הקובץ שלנו. 56 00:02:59,080 --> 00:03:03,140 הפונקציה המחזירה את מצביע זה, fopen, לוקחת שני טיעונים. 57 00:03:03,140 --> 00:03:07,440 הראשון הוא שם הקובץ כולל סיומת הקובץ, אם מתאים. 58 00:03:07,440 --> 00:03:10,980 תזכיר כי סיומת קובץ אינה משפיעה על הקובץ ברמה הנמוכה ביותר. 59 00:03:10,980 --> 00:03:14,640 אנחנו תמיד להתמודד עם רצף ארוך של אפסים ואחדים. 60 00:03:14,640 --> 00:03:19,630 אבל זה עושה השפעה כמה קבצים ויישומים פרשו מה הם משמשים לפתיחתם. 61 00:03:19,630 --> 00:03:22,290 הטיעון השני לfopen הוא אות אחת 62 00:03:22,290 --> 00:03:25,300 שמייצג את מה שאנחנו מתכננים לעשות אחרי שפותחים את הקובץ. 63 00:03:25,300 --> 00:03:30,630 ישנן שלוש אפשרויות לטיעון זה - W, R, וא 64 00:03:30,630 --> 00:03:34,900 אנחנו בחרנו w במקרה זה משום שאנחנו רוצים לכתוב לקובץ. 65 00:03:34,900 --> 00:03:38,820 R, כפי שאתם יכולים לנחש, הוא לקריאה לקובץ. 66 00:03:38,820 --> 00:03:41,760 וזה לשרשור לקובץ. 67 00:03:41,760 --> 00:03:44,960 בעוד הן w וניתן להשתמש בו לכתיבה לקבצים, 68 00:03:44,960 --> 00:03:47,460 w יתחיל לכתוב מההתחלה של הקובץ 69 00:03:47,460 --> 00:03:50,810 ואפשרות להחליף את כל נתונים, כי בעבר היה מאוחסנים. 70 00:03:50,810 --> 00:03:54,070 כברירת מחדל, קובץ נפתחנו, אם הוא לא קיים, 71 00:03:54,070 --> 00:03:57,180 נוצר בספרייה שלנו עובדת כיום. 72 00:03:57,180 --> 00:04:00,540 עם זאת, אם אנחנו רוצים לגשת או ליצור קובץ במיקום אחר, 73 00:04:00,540 --> 00:04:02,650 בטיעון הראשון של fopen, 74 00:04:02,650 --> 00:04:05,840 אנחנו יכולים לציין נתיב קובץ בנוסף לשם הקובץ. 75 00:04:05,840 --> 00:04:09,490 בעוד החלק הראשון של התהליך הזה הוא רק שורה אחת של קוד ארוך, 76 00:04:09,490 --> 00:04:12,350 מומלץ תמיד טוב לכלול קבוצה נוספת של קווים 77 00:04:12,350 --> 00:04:15,930 שתבדוק על מנת להבטיח שהקובץ נפתח בהצלחה או שנוצר. 78 00:04:15,930 --> 00:04:20,300 אם fopen מחזיר null, לא הייתי רוצה לפרוץ קדימה עם התכנית שלנו, 79 00:04:20,300 --> 00:04:23,270 וזה יכול לקרות אם מערכת ההפעלה היא מתוך זיכרון 80 00:04:23,270 --> 00:04:27,940 או אם ננסה לפתוח קובץ בספרייה שעבורו לא הייתה לו ההרשאות המתאימות. 81 00:04:27,940 --> 00:04:31,780 >> החלק השני של התהליך מתרחש בלולאה בזמן של מכונת הכתיבה. 82 00:04:31,780 --> 00:04:35,000 אנו משתמשים בפונקצית ספריית CS50 כדי לקבל קלט מהמשתמש, 83 00:04:35,000 --> 00:04:37,190 ובהנחה שהם לא רוצים לצאת מהתכנית, 84 00:04:37,190 --> 00:04:41,940 אנו משתמשים בפונקציה fputs לקחת המחרוזת ולכתוב אותו לקובץ. 85 00:04:41,940 --> 00:04:46,700 fputs הוא רק אחת מהפונקציות הרבות שאנו יכולים להשתמש בו כדי לכתוב לקובץ. 86 00:04:46,700 --> 00:04:51,920 אחרים כוללים fwrite, fputc, ואפילו fprintf. 87 00:04:51,920 --> 00:04:54,840 ללא קשר לפונקציה המסוימת שלמרות שאסיים בשימוש,, 88 00:04:54,840 --> 00:04:57,480 כולם צריך לדעת, באמצעות טיעוניהם, 89 00:04:57,480 --> 00:04:59,670 לפחות שני דברים - 90 00:04:59,670 --> 00:05:03,140 מה צריך להיות כתוב ובו היא צריכה להיות כתובה. 91 00:05:03,140 --> 00:05:07,240 במקרה שלנו, קלט הוא המחרוזת שצריכה להיות כתובים 92 00:05:07,240 --> 00:05:11,290 וfp הוא מצביע שמכוון אותנו למקום שאנחנו כותבים. 93 00:05:11,290 --> 00:05:15,330 בתכנית זו, חלק השני של התהליך הוא די פשוט. 94 00:05:15,330 --> 00:05:17,360 אנחנו פשוט לוקחים את מחרוזת מהמשתמש 95 00:05:17,360 --> 00:05:22,120 והוספתו ישירות לקובץ שלנו עם מעט לשום אימות קלט או בדיקות בטחוניות. 96 00:05:22,120 --> 00:05:26,160 אולם לעתים קרובות, חלק 2 ייקח את עיקר הקוד שלך. 97 00:05:26,160 --> 00:05:30,580 לבסוף, חלק 3 הוא בקו 58, שבו אנחנו לסגור את התיק. 98 00:05:30,580 --> 00:05:34,860 כאן אנו קוראים fclose ולהעביר את מצביע הקובץ המקורי שלנו. 99 00:05:34,860 --> 00:05:39,500 בשורה שלאחר מכן, אנחנו חוזרים אפס, מסמנים את הסוף של התכנית שלנו. 100 00:05:39,500 --> 00:05:42,630 וכן, חלק 3 הוא פשוט כמו זה. 101 00:05:42,630 --> 00:05:45,260 >> בואו נעבור לקריאת קבצים. 102 00:05:45,260 --> 00:05:48,220 חזור בספרייה שלנו יש לנו קובץ בשם printer.c. 103 00:05:48,220 --> 00:05:50,910 בואו להפעיל אותו בקובץ שזה עתה יצר - 104 00:05:50,910 --> 00:05:53,350 doc.txt. 105 00:05:53,350 --> 00:05:58,150 תכנית זו, כפי שהשם מרמז, פשוט להדפיס את תוכן הקובץ המועברים אליו. 106 00:05:58,150 --> 00:06:00,230 ויש לנו את זה. 107 00:06:00,230 --> 00:06:03,780 את שורות קוד שכבר הקלידו קודם ונשמרו בdoc.txt. 108 00:06:03,780 --> 00:06:06,980 היי. השמי הוא ג'ייסון. 109 00:06:06,980 --> 00:06:09,120 אם אנחנו צוללים לתוך printer.c, 110 00:06:09,120 --> 00:06:13,570 אנחנו רואים שהרבה קוד נראה דומה למה שאנו פשוט הסתובבנו בtypewriter.c. 111 00:06:13,570 --> 00:06:16,720 ואכן קו 22, שבו פתחנו את הקובץ, 112 00:06:16,720 --> 00:06:19,220 וקו 39, שבו סגרנו את הקובץ, 113 00:06:19,220 --> 00:06:23,890 שניהם כמעט זהים לtypewriter.c, לחסוך לטענה שנייה fopen. 114 00:06:23,890 --> 00:06:26,510 הפעם אנחנו קוראים מקובץ, 115 00:06:26,510 --> 00:06:29,040 כך שבחרנו r במקום W. 116 00:06:29,040 --> 00:06:31,950 לכן, בואו נתמקד בחלק השני של התהליך. 117 00:06:31,950 --> 00:06:36,060 בקו 35, כתנאי שני ב4 הלולאה שלנו, 118 00:06:36,060 --> 00:06:38,590 אנחנו עושים את שיחה לfgets, 119 00:06:38,590 --> 00:06:42,190 פונקצית לווית fputs מקודם. 120 00:06:42,190 --> 00:06:44,660 הפעם יש לנו שלוש טענות. 121 00:06:44,660 --> 00:06:48,810 הראשון הוא מצביע למערך של תווים שבו יאוחסן המחרוזת. 122 00:06:48,810 --> 00:06:52,670 השני הוא מספר תווים המרבי לקריאה. 123 00:06:52,670 --> 00:06:56,010 והשלישי הוא מצביע לקובץ שבה אנחנו עובדים. 124 00:06:56,010 --> 00:07:00,780 תוכל להבחין כי ללולאה מסתיימת כאשר fgets מחזיר null. 125 00:07:00,780 --> 00:07:02,940 יש שתי סיבות שזה יכול היה לקרות. 126 00:07:02,940 --> 00:07:05,380 ראשית, ייתכן שחלה טעות. 127 00:07:05,380 --> 00:07:10,740 שנית, ויותר סביר, סוף הקובץ הושג ולא עוד דמויות היו לקרוא. 128 00:07:10,740 --> 00:07:14,040 במקרה שאתה תוהה, שתי פונקציות קיימות שייאפשרו לנו לספר לי 129 00:07:14,040 --> 00:07:17,160 שהסיבה היא הסיבה למצביע null המסוים הזה. 130 00:07:17,160 --> 00:07:21,090 וגם, באופן לא מפתיע, מכיוון שהם צריכים לעשות עם העבודה עם קבצים, 131 00:07:21,090 --> 00:07:26,940 גם פונקצית ferror ולהתחיל לתפקד feof באות ו. 132 00:07:26,940 --> 00:07:32,130 >> לבסוף, לפני שאנחנו מסיקים, הערה אחת מהירה על סיום תפקיד קובץ, 133 00:07:32,130 --> 00:07:36,690 אשר, כפי שהזכיר זה עתה, נכתב כfeof. 134 00:07:36,690 --> 00:07:41,550 לעתים קרובות תמצא את עצמך משתמש בזמן וללולאות בהדרגה לקרוא את דרכך בקבצים. 135 00:07:41,550 --> 00:07:45,790 לפיכך, תצטרך דרך לסיים לולאות אלה לאחר שתגיע לסוף של קבצים אלה. 136 00:07:45,790 --> 00:07:50,510 קוראים feof על מצביע הקובץ שלך ובדיקה כדי לראות אם זה נכון 137 00:07:50,510 --> 00:07:52,310 היה עושה בדיוק את זה. 138 00:07:52,310 --> 00:07:59,820 לפיכך, בעוד לולאה עם התנאי (! Feof (FP)) אולי נראית כמו פתרון מושלם מתאים. 139 00:07:59,820 --> 00:08:03,770 עם זאת, אומר שיש לנו שורה אחת השאירה בקובץ הטקסט שלנו. 140 00:08:03,770 --> 00:08:07,130 אנחנו להיכנס הלולאה בזמננו והכל יסתדר כמתוכנן. 141 00:08:07,130 --> 00:08:12,750 בסיבוב הבא דרך, התכנית שלנו תהיה לבדוק אם feof של fp הוא נכון, 142 00:08:12,750 --> 00:08:15,430 אבל - וזו נקודה חשובה להבין כאן - 143 00:08:15,430 --> 00:08:17,770 זה לא יהיה נכון כרגע. 144 00:08:17,770 --> 00:08:21,110 זאת משום שהמטרה היא feof לא לבדוק 145 00:08:21,110 --> 00:08:24,400 אם השיחה הבאה לפונקציה לקרוא תפגע סוף הקובץ, 146 00:08:24,400 --> 00:08:28,190 אלא כדי לבדוק אם לא הסוף של הקובץ כבר הגיע. 147 00:08:28,190 --> 00:08:30,140 במקרה של דוגמה זו, 148 00:08:30,140 --> 00:08:32,780 לקרוא את השורה האחרונה של הקובץ שלנו עובר בצורה חלקה לחלוטין, 149 00:08:32,780 --> 00:08:36,210 אבל התכנית עדיין אינה יודעת שאנחנו נגיע לסוף הקובץ שלנו. 150 00:08:36,210 --> 00:08:40,549 זה לא שהיא עושה עד לקריאה נוספת אחת שדלפקי סוף הקובץ. 151 00:08:40,549 --> 00:08:43,210 לפיכך, מצב נכון יהיה הבא: 152 00:08:43,210 --> 00:08:49,330 fgets ושלושה טיעוניה - פלט, גודל של פלט, וFP - 153 00:08:49,330 --> 00:08:52,570 וכל זה אינו שווה לnull. 154 00:08:52,570 --> 00:08:55,260 זו הגישה שנקטנו בprinter.c, 155 00:08:55,260 --> 00:08:57,890 ובמקרה הזה, לאחר יציאת לולאה, 156 00:08:57,890 --> 00:09:04,290 אתה יכול לקרוא לfeof או ferror להודיע ​​למשתמש כלהנמקה הספציפית ליציאה מהלולאה הזו. 157 00:09:04,290 --> 00:09:08,100 >> כתיבה ולקריאת מקובץ היא, ברמה הבסיסית ביותר, 158 00:09:08,100 --> 00:09:10,150 תהליך פשוט 3-חלק. 159 00:09:10,150 --> 00:09:12,530 ראשית, עלינו לפתוח את הקובץ. 160 00:09:12,530 --> 00:09:16,740 שנית, אנחנו שמים כמה דברים לקובץ שלנו או לקחת כמה דברים מחוץ לזה. 161 00:09:16,740 --> 00:09:19,200 שלישית, אנו לסגור את התיק. 162 00:09:19,200 --> 00:09:21,170 החלקים הראשונים ואחרונים הם קלים. 163 00:09:21,170 --> 00:09:23,920 החלק האמצעי הוא מקום שבי החומר המסובך שקרים. 164 00:09:23,920 --> 00:09:27,760 ולמרות שמתחת למכסת המנוע שאנחנו תמיד להתמודד עם רצף ארוך של אפסים ואחדים, 165 00:09:27,760 --> 00:09:30,710 זה עוזר כאשר קידוד כדי להוסיף שכבה של הפשטה 166 00:09:30,710 --> 00:09:35,350 שהופך את הרצף למשהו שדומה יותר למה שאנחנו רגילים לראות. 167 00:09:35,350 --> 00:09:39,570 לדוגמה, אם אנחנו עובדים עם קובץ מפה סיבית 24-bit, 168 00:09:39,570 --> 00:09:43,290 אנחנו בטח יהיו קריאה או כתיבה של 3 בתים בכל פעם. 169 00:09:43,290 --> 00:09:46,450 במקרה כזה, זה יהיה הגיוני להגדיר כראוי ושם 170 00:09:46,450 --> 00:09:48,980 struct שהוא גדול 3 בתים. 171 00:09:48,980 --> 00:09:51,410 >> למרות שעבודה עם קבצים אולי נראית מסובכת, 172 00:09:51,410 --> 00:09:54,530 ניצולם מאפשר לנו לעשות משהו באמת יוצא דופן. 173 00:09:54,530 --> 00:09:58,880 אנחנו יכולים לשנות את מצבו של העולם מחוץ לתכנית שלנו, 174 00:09:58,880 --> 00:10:01,730 אנחנו יכולים ליצור משהו שחי מעבר לחייו של התכנית שלנו, 175 00:10:01,730 --> 00:10:07,190 או שאנחנו יכולים גם לשנות משהו שנוצר לפני התכנית שלנו התחילה לרוץ. 176 00:10:07,190 --> 00:10:11,210 אינטראקציה עם קבצים היא חלק חזק באמת של תכנות ב C. 177 00:10:11,210 --> 00:10:15,300 ואני מתרגש לראות את מה שאתה הולך ליצור עימו בקוד הבא. 178 00:10:15,300 --> 00:10:19,770 השמי הוא ג'ייסון הירשהורן. זה CS50. 179 00:10:19,770 --> 00:10:21,770 [CS50.TV] 180 00:10:21,770 --> 00:10:25,940 >> [שחוק] 181 00:10:25,940 --> 00:10:29,330 אוקיי. טייק אחד. הנה אנחנו מתחילים. 182 00:10:49,000 --> 00:10:52,140 כאשר אנו חושבים על קובץ - >> אה, הרגע. סליחה. 183 00:10:52,140 --> 00:10:56,800 [שחוק] אוקיי. 184 00:11:06,620 --> 00:11:09,970 היי שם. 185 00:11:13,670 --> 00:11:16,310 כאשר אנו חושבים על קובץ - 186 00:11:17,610 --> 00:11:20,710 כאשר אתה חושב על קובץ - אוקיי. תגיד לי כשאתה מוכן. 187 00:11:20,710 --> 00:11:22,520 אוי, גדול. 188 00:11:22,520 --> 00:11:26,180 למרות קריאת טלפרומפטר אולי נראה - לא. שלי רע.