לדלג לתוכן

4.2 קבצים הרצאה

הקדמה

  • ממליץ לראות את ההרצאה המוקלטת של הפרק זה! מסביר בה המון באגים שעלולים לבוא בשימוש עם קבצים, איך להימנע ומראה דיבוג בלייב של תוכנה

פעולות על קבצים

  • זה מאוד נפוץ לכתוב קוד ששומר מידע וקורא מקבצים במחשב.
  • לפעמים נרצה לכתוב קוד ששומר מידע על האחסון של המחשב.
  • שימו לב, כשאנחנו כותבים קוד שמבצע פעולות על קבצים אנחנו תמיד נתחיל בלקרוא לפונקציה שאחראית "לפתוח" את הקובץ, ונסיים בפונקציה שאחראית "לסגור" את הקובץ, הסיבה לכך היא שאנחנו רוצים להכריז על כך שאנחנו מתחילים שימוש בקובץ וכשאנחנו מסיימים איתו.

דוגמאות

יצירת קובץ

file = open("my_file.txt", "x")
file.close()

- כאשר אנחנו קוראים לפונקציה open אנחנו מכריזים שאנחנו עומדים להשתמש בקובץ מסויים, אחרכך כך אנחנו מציינים בפרמטר השני באיזה צורה אנחנו נפתח את הקובץ - למשל בדוגמה הזו הבאנו פרמטר: "x" וזה בעצם יצור את הקובץ, קיימות עוד פעולות כמו "'w", או "r" ונעבור עליהם בהמשך.
- אחרי שסיימנו עם הפתיחה של הקובץ אנחנו צריכים לסגור אותו, לקרוא לclose - ובכך אנחנו מגדירים שסיימנו לעבוד עם הקובץ, זה לא מוחק אותו. רק פשוט אומר שאנחנו כבר לא עושים איתו כלום יותר בתוכנה.

יצירת קובץ וכתיבה אילו

file = open(r"my_file_2.txt", "w")  # Open a new file for writing  
file.write("some content!!!!!!")  # Writing content to the file  
file.close()  # Closing the file and saving the written content

- בקובץ הזה עשינו open ובשונה מפעם שעברה, העברנו "w" לopen, שזה קיצור של write - כתיבה. מקודם העברנו "x" שמשמש רק ליצירה של קובץ. זה אומר שהפעם נוכל גם לכתוב לקובץ, שימו לב שישר אחרכך קראנו לפונקציה write שכותבת את התוכן שבחרנו לקובץ
- תזכורת: כל פעולה של קובץ מתחילה בopen ונגמרת בclose.
- נקודה חשובה: המוד "w" משמש לכתיבה לקובץ, אבל כאשר אנחנו עושים write הוא מחליף את התוכן שהיה מקודם, זה אומר שאם היה לפני הפעולה write תוכן לקובץ, הוא יוחלף בתוכן החדש.

קריאה מקובץ

file = open(r"my_file.txt", "r")  # Open a new file for writing  
content = file.read()  # Reading content from the file  
print(content) # Printing the content 
file.close()  # Closing the file and saving the current content

- כמו שאנחנו יכולים לכתוב לקובץ, נוכל גם לקרוא ממנו, הפעם נעביר פרמטר "r" לopen כדי לציין שאנחנו פותחים את הקובץ לקריאה. אחרכך נקרא לפונקציה read שתחזיר לנו מחרוזת שתכיל את התוכן של הקובץ.

כתיבה וקריאה מקובץ

  • מה אם נרצה לכתוב לקובץ, ואז בשלב מסויים לקרוא אותו? נוכל לעשות זאת בקלות בקוד הבא:
    file = open(r"my_file.txt", "w")
    file.write("some content!!!!!!")
    file.close()
    
    file = open(r"my_file.txt", "r")
    content = file.read()
    print(content)
    file.close()
    
  • אבל הפעולה הזו דרשה מאיתנו לפתוח ולסגור את הקובץ מספר פעמים, מה אם נרצה לפתוח קובץ גם לכתיבה וגם לקריאה? נוכל לעשות זאת באמצעות:
    file = open(r"my_file.txt", "w+")  # Open a new file for writing  
    
  • כאשר "w+" יפתח קובץ גם לכתיבה וגם לקריאה, גם "r+" יעשה אותו הדבר
  • אבל אנחנו נתקלים בבעיה, למעשה כאשר עושים write לתוכן לקובץ, זה לא שומר את התוכן שכתבנו עד שקורה close. זה אומר שאחרי שאנחנו עושים file.write אנחנו צריכים לעשות file.close כדי לשמור את התוכן שכתבנו לקובץ.
  • בגלל הבעיה הזו אנחנו לא נוכל לכתוב קוד שגם כותב ואז קורא מקובץ מבלי לעשות close, אבל קיים פתרון שיכול לעזור לנו והוא נקרא flush.
  • הפונקציה flush שומרת את כל התוכן שנכתב עד כו עם write לקובץ מבלי לעשות close.
  • למעשה אחרכך אנחנו נתקלים בעוד בעיה: לכל קובץ קיים מצביע, וכאשר אנחנו כותבים לקובץ, אנחנו מזיזים את המצביע שלו למקום שבו כתבנו, כך שאם נעשה write לקובץ, מצביע הקובץ יזוז לסוף הקובץ, ואז שננסה לקרוא מהקובץ הוא ינסה לקרוא מסוף הקובץ.
  • אז כדי לפתור את הבעיה נזיז את המצביע של הקובץ לתחילת הקובץ לפני שאנחנו קוראים ממנו, ונעשה זאת באמצעות הפונקציה seek, כאשר היא מקבלת כפרמטר את האות שאלייה להצביע - במקרה שלנו נרצה שהמבציע יצביע לתחילת הקובץ אז נביא לה 0, כדי שיצביע על האות הראשונה.
    file = open(r"my_file.txt", "w+")  # Open a new file for writing  and reading
    
    file.write("some content!!!!!!")  # Writing content to the file
    file.flush() # saving the content to file
    
    file.seek(0) # moving file pointer to start
    content = file.read()  # Reading content from the file
    print(content) # Printing the content
    
    file.close()  # Closing the file and saving the written content
    
  • הפונקציה flush - הפונקציה מאפשרת לנו לשמור את התוכן שעד כו כתבנו לקובץ מבלי לסגור אותו:
    במקרה הזה הפונקציה flush שומרת את התוכן שכתבנו עם write לקובץ, (במקום close) כך שנוכל לקרוא אותו שנעשה read ישר אחרכך.
  • הפונקציה seek משנה את המצביע של הקובץ (במקרה הזה להתחלה) כדי שנוכל לקרוא את הקובץ מההתחלה. על מנת להסביר יכלנו לעשות file.seek(5) - ובכך לקרוא מהאות החמישית בקובץ והלאה.

הרחבת קובץ

  • ומה אם נרצה להוסיף תוכן לקובץ מבלי למחוק את התוכן שכבר קיים? בעצם רק להרחיב את הקובץ? נעשה זאת באמצעות "a", קיצור של append - הרחבה

    file = open(r"my_file.txt", "a")  # Open a new file for writing  
    file.write("\nmore content!!!!!!")  # Appending content to the file  
    file.close()  # Closing the file and saving the written content
    

  • פתיחה להוספת תוכן + קריאה

    file = open(r"my_file.txt", "a+")  # Open a new file for writing  
    
    file.write("\nmore and more content!!!!!!")  # Appending content to the file
    file.flush()
    file.seek(0)
    content = file.read()  # Reading content from the file  
    print(content) # Printing the content 
    
    file.close()  # Closing the file and saving the written content
    

תוכנה לדוגמה - עורך קבצים.

  • התוכנה הבאה מאפשרת לנו לערוך קובץ על המחשב.
    print("welcome to my text editor! to exit write - /quit")  
    
    file_path = input("enter a file to edit: ")
    file = open(file_path, "a+")  # Open a new file for writing  
    
    sentence = ""  
    while sentence.removesuffix("\n") != "/q":  
        sentence = input("> ") + "\n"  
        file.write(sentence)  # Appending content to the file  
        file.flush()  # Saving the written content  
    
    file.close()  # Closing the file and saving the written content
    

מנהל קונטקסט - context manager

  • עד כו כל פעם שרצינו להתנהל מול קובץ היינו צריכים לפתוח ולסגור אותו, זה פעולה שחוזרת על עצמה המון, בפייתון אפשר להשתמש במנהל קונטקסט כדי לחסוך את זה מאיתנו את הפעולת סגירה בסוף.
    with open(r"C:\Users\Amit\Desktop\my_file", "r") as file:
        content = file.read()
        print(content)
    
  • שימוש בwith ו - as
  • מנהל קונטקסט הופך את הקוד שלנו לנקי יותר רוב הפעמים,
  • מנהל קונטקסט שימושי לא רק בקבצים, אלה גם בהמון דברים אחרים (נלמד בהמשך)
  • מנהל קונטקסט דואג שאנחנו לא שוכחים לסגור את הקבצים!