מלבד היישומים הפשוטים ביותר, על רוב התוכניות לקרוא או לכתוב קבצים. יתכן שזה נועד רק לקריאת קובץ config, או לנתח טקסט או משהו מתוחכם יותר. מדריך זה מתמקד בשימוש בקבצי גישה אקראית ב- C.
תכנות קלט / פלט של קובץ גישה אקראית ב- C

פעולות הקבצים הבסיסיות הן:
- fopen - פתח קובץ - ציין כיצד הוא נפתח (לקרוא / לכתוב) וסוג (בינארי / טקסט)
- fclose - סגור קובץ שנפתח
- fread - לקרוא מתוך קובץ
- fwrite - כתוב לקובץ
- fseek / fsetpos - העבירו את מצביע הקובץ למקום כלשהו בקובץ
- ftell / fgetpos - גלה היכן ממוקם מצביע הקבצים
שני סוגי הקבצים הבסיסיים הם טקסט ו- בינארי. מבין שני אלה, קבצים בינאריים בדרך כלל פשוטים יותר להתמודד איתם. מסיבה זו והעובדה שגישה אקראית בקובץ טקסט אינה דבר שעליך לעשות לעתים קרובות, הדרכה זו מוגבלת לקבצים בינאריים. ארבע הפעולות הראשונות המפורטות לעיל מיועדות הן לקבצי טקסט והן לקבצי גישה אקראית. השניים האחרונים רק לגישה אקראית.
גישה אקראית פירושה שתוכל לעבור לכל חלק בקובץ ולקרוא או לכתוב נתונים ממנו מבלי שתצטרך לקרוא את כל הקובץ. לפני שנים, נתונים נשמרו על גלגלים גדולים של קלטת מחשב. הדרך היחידה להגיע לנקודה בקלטת הייתה לקרוא את כל הקלטת. ואז הגיעו דיסקים ועכשיו תוכלו לקרוא כל חלק בקובץ ישירות.
תכנות עם קבצים בינאריים
קובץ בינארי הוא קובץ בכל אורך המחזיק בתים עם ערכים בטווח 0 עד 255. לבתים אלה אין משמעות אחרת שלא כמו בקובץ טקסט שבו ערך 13 פירושו החזרת הובלה, 10 פירושו הזנת שורות ו -26 פירושו סוף הקובץ. תוכנה הקוראת קבצי טקסט נאלצת להתמודד עם המשמעויות האחרות הללו.
קבצים בינאריים זרם של בתים ושפות מודרניות נוטים לעבוד עם זרמים ולא עם קבצים. החלק החשוב הוא זרם הנתונים ולא מאיפה הוא הגיע. בתוך ג, אתה יכול לחשוב על הנתונים כקבצים או כזרמים. עם גישה אקראית, אתה יכול לקרוא או לכתוב לכל חלק בקובץ או בזרם. עם גישה רציפה, אתה צריך לעבור דרך הקובץ או להזרים מההתחלה כמו קלטת גדולה.
דוגמת קוד זו מציגה קובץ בינארי פשוט שנפתח לכתיבה, ובתוכו כתוב מחרוזת טקסט (char *). בדרך כלל אתה רואה זאת עם קובץ טקסט, אך אתה יכול לכתוב טקסט לקובץ בינארי.
דוגמה זו פותחת קובץ בינארי לכתיבה ואז כותבת לתוכו char * (מחרוזת). המשתנה FILE * מוחזר משיחת ה- fopen (). אם זה נכשל (הקובץ עשוי להתקיים ולהיות פתוח או לקריאה בלבד או שעלולה להיות תקלה בשם הקובץ), הוא יחזיר 0.
הפקודה fopen () מנסה לפתוח את הקובץ שצוין. במקרה זה, זה test.txt באותה תיקיה כמו היישום. אם הקובץ כולל נתיב, יש להכפיל את כל הקו האחורי. "c: \ תיקייה \ test.txt" אינו נכון; עליך להשתמש ב" c: \\ תיקייה \\ test.txt ".
מכיוון שמצב הקובץ הוא "wb", קוד זה כותב לקובץ בינארי. הקובץ נוצר אם הוא לא קיים, ואם כן, כל מה שהיה בו יימחק. אם הקריאה ל- fopen נכשלת, אולי מכיוון שהקובץ היה פתוח או שהשם מכיל תווים לא חוקיים או נתיב לא חוקי, fopen מחזיר את הערך 0.
למרות שאתה יכול פשוט לבדוק אם ה- ft אינו אפס (הצלחה), לדוגמה זו יש פונקציית FileSuccess () כדי לעשות זאת במפורש. ב- Windows זה מוציא את ההצלחה / כישלון השיחה ושם הקובץ. זה קצת מכביד אם אתה אחרי הביצועים, אז אתה עלול להגביל את זה לניפוי באגים. במערכת Windows, מעט מאוד תקורות מוציאות טקסט לבאגי המערכת.
ה- fwrite () קורא פלט את הטקסט שצוין. הפרמטרים השני והשלישי הם גודל התווים ואורך המיתר. שניהם מוגדרים כגודל_t שהוא מספר שלם שאינו חתום. התוצאה של שיחה זו היא לכתוב ספירת פריטים בגודל שצוין. שים לב שעם קבצים בינאריים, למרות שאתה כותב מחרוזת (char *), זה לא מוסיף שום תו חזרה או עגלה. אם אתה רוצה כאלה, עליך לכלול אותם במפורש במחרוזת.
מצבי קבצים לקריאה וכתיבה של קבצים
כשאתה פותח קובץ, אתה מציין כיצד לפתוח אותו - האם ליצור אותו מחדש או להחליף אותו והאם זה טקסט או בינארי, לקרוא או לכתוב ואם ברצונך לצרף אותו. זה נעשה באמצעות מפרט מצב קובץ אחד או יותר שהם אותיות בודדות "r", "b", "w", "a" ו- "+" בשילוב עם האותיות האחרות.
- r - פותח את הקובץ לקריאה. זה נכשל אם הקובץ לא קיים או לא ניתן למצוא אותו.
- w - פותח את הקובץ כקובץ ריק לכתיבה. אם הקובץ קיים, תוכנו נהרס.
- א - פותח את הקובץ לכתיבה בסוף הקובץ (מצורף) מבלי להסיר את הסמן EOF לפני כתיבת נתונים חדשים לקובץ; זה יוצר את הקובץ תחילה אם הוא לא קיים.
הוספת "+" למצב הקובץ יוצרת שלושה מצבים חדשים:
- r + - פותח את הקובץ לקריאה וכתיבה כאחד. (הקובץ חייב להתקיים.)
- w + - פותח את הקובץ כקובץ ריק לקריאה וכתיבה כאחד. אם הקובץ קיים, תוכנו נהרס.
- a + - פותח את הקובץ לקריאה וצירוף; הפעולה המצורפת כוללת את הסרת הסמן של EOF לפני שנכתבים נתונים חדשים לקובץ, וסמן ה- EOF משוחזר לאחר השלמת הכתיבה. זה יוצר את הקובץ תחילה אם הוא לא קיים. פותח את הקובץ לקריאה וצירוף; הפעולה המצורפת כוללת את הסרת הסמן של EOF לפני שנכתבים נתונים חדשים לקובץ, וסמן ה- EOF משוחזר לאחר השלמת הכתיבה. זה יוצר את הקובץ תחילה אם הוא לא קיים.
שילובי מצב קבצים
טבלה זו מציגה שילובי מצב קבצים עבור קבצי טקסט וקבצים בינאריים כאחד. באופן כללי, אתה קורא מקובץ טקסט או כותב אותו, אך לא את שניהם בו זמנית. בעזרת קובץ בינארי תוכלו לקרוא ולכתוב לאותו קובץ. הטבלה שלהלן מראה מה תוכלו לעשות עם כל שילוב.
- טקסט - קריאה
- rb + בינארי - לקרוא
- r + טקסט - לקרוא, לכתוב
- r + b בינארי - לקרוא, לכתוב
- rb + בינארי - לקרוא, לכתוב
- w טקסט - לכתוב, ליצור, לקצץ
- wb בינארי - לכתוב, ליצור, לקצץ
- w + טקסט - לקרוא, לכתוב, ליצור, לקצץ
- w + b בינארי - לקרוא, לכתוב, ליצור, לקצץ
- wb + בינארי - לקרוא, לכתוב, ליצור, לקצץ
- טקסט - כתוב, צור
- ab בינארי - לכתוב, ליצור
- טקסט + - לקרוא, לכתוב, ליצור
- a + b בינארי - כתוב, צור
- ab + בינארי - לכתוב, ליצור
אלא אם אתה פשוט יוצר קובץ (השתמש "wb") או רק קורא קובץ אחד (השתמש "rb"), אתה יכול להתחמק עם השימוש "w + b".
יישומים מסוימים מאפשרים גם אותיות אחרות. מיקרוסופטלמשל מאפשר:
- מצב טקסט -
- ג - להתחייב
- n - לא מתחייב
- S - ביצוע מיטוב במטמון לגישה רציפה
- R - מטמון לא רצף (גישה אקראית)
- T - זמני
- D - מחק / זמני, ההורג את הקובץ כשהוא סגור.
אלה אינם ניידים אז השתמש בהם בסכנתך.
דוגמה לאחסון קבצים בגישה אקראית
הסיבה העיקרית לשימוש בקבצים בינאריים היא הגמישות המאפשרת לקרוא או לכתוב בכל מקום בקובץ. קבצי טקסט מאפשרים לך לקרוא או לכתוב ברצף בלבד. עם השכיחות של מסדי נתונים זולים או בחינם כגון SQLite ו MySQL, מקטין את הצורך להשתמש בגישה אקראית על קבצים בינאריים. עם זאת, גישה אקראית לרשומות קבצים מעט מיושנת אך עדיין שימושית.
בחינת דוגמא
נניח שהדוגמה מציגה צמד אינדקס וקבצי נתונים המאחסנים מחרוזות בקובץ גישה אקראי. המיתרים באורכים שונים והם צמודים לאינדקס לפי מיקום 0, 1 וכן הלאה.
ישנן שתי פונקציות בטלות: CreateFiles () ו- ShowRecord (int recnum). CreateFiles משתמש במאגר char * בגודל 1100 כדי להחזיק מחרוזת זמנית המורכבת ממחרוזת הפורמט msg ואחריו n כוכביות בהן n משתנה בין 5 ל- 1004. שני קבצים * נוצרים שניהם באמצעות filemode wb במשתנים ftindex ו- ftdata. לאחר היצירה משתמשים בהם כדי לתפעל את הקבצים. שני הקבצים הם
- index.dat
- data.dat
קובץ האינדקס מכיל 1000 רשומות מסוג סוג עצמאי; זהו סוג ה- indextype הבנוי, בו שני העמודים (מהסוג fpos_t) וגודל. החלק הראשון של הלולאה:
מאכלס את המחרוזת msg כך.
וכולי. ואז זה:
מאכלס את המבנה באורך המיתר ונקודה בקובץ הנתונים בו ייכתב המחרוזת.
בנקודה זו, ניתן לכתוב הן את קובץ האינדקס והן את מחרוזת קובץ הנתונים לקבצים שלהם. למרות שמדובר בקבצים בינאריים, הם נכתבים ברצף. בתיאוריה, אתה יכול לכתוב רשומות למצב שמעבר לסוף הקובץ הנוכחי, אבל זו לא טכניקה טובה לשימוש וכנראה שגם לא ניידת.
החלק האחרון הוא לסגור את שני הקבצים. זה מבטיח כי החלק האחרון של הקובץ נכתב לדיסק. במהלך כתיבת קבצים, רבים מהכתבים אינם עוברים ישירות לדיסק אלא מוחזקים במאגר בגודל קבוע. לאחר כתיבה ממלאת את המאגר, כל תוכן המאגר נכתב לדיסק.
פונקציית שטיפה של קבצים מאלצת את השטיפה ותוכל גם לציין אסטרטגיות שטיפת קבצים, אך אלה מיועדות לקבצי טקסט.
פונקצית ShowRecord
כדי לבדוק שאפשר לאחזר כל רשומה שצוינה מקובץ הנתונים, עליכם לדעת שני דברים: היכן הוא מתחיל בקובץ הנתונים וכמה הוא גדול.
זה מה שקובץ האינדקס עושה. הפונקציה ShowRecord פותחת את שני הקבצים, מבקשת לנקודה המתאימה (recnum * sizeof (indextype) ומביאה מספר בתים = sizeof (index)).
SEEK_SET הוא קבוע שמציין מהיכן נעשה המדגם. ישנם שני קבועים נוספים המוגדרים לכך.
- SEEK_CUR - חפש ביחס למיקום הנוכחי
- SEEK_END - חפש מוחלט מסוף הקובץ
- SEEK_SET - חפשו באופן מוחלט מתחילת הקובץ
אתה יכול להשתמש SEEK_CUR כדי להזיז את מצביע הקבצים קדימה לפי גודל (אינדקס).
לאחר השגת גודל הנתונים ומיקומם, נותר רק להביא אותם.
הנה, השתמש ב- fsetpos () בגלל סוג ה- index.pos שהוא fpos_t. דרך חלופית היא להשתמש ב ftell במקום fgetpos ו- fsek במקום fgetpos. הזוג fseek ו- ftell עובדים עם int ואילו fgetpos ו- fsetpos משתמשים ב- fpos_t.
לאחר קריאת הרשומה לזיכרון, מצורף תו null 0 כדי להפוך אותו לתקין מחרוזת c. אל תשכח את זה או שתתרסק. כמו קודם, fclose נקרא בשני הקבצים. למרות שלא תאבד נתונים כלשהם אם תשכח את fclose (שלא כמו כותב), תהיה לך דליפת זיכרון.