###### tags: `python` # 檔案存取 ## 路徑 * 相對路徑: * 以目前python程式碼檔案所在位置為基準,標示另外檔案所在位置 * 開發專案建議使用相對路徑標示,方便未來重複使用較方便 * 絕對路徑: * 從磁碟機根目錄為基準,標示另外檔案所在位置 ## 檔案 * 不管是只要讀取檔案內容或是修改檔案內容,都必須先開啟檔案 * 檔案使用完畢請關閉檔案,釋放記憶體空間 開啟模式 | 模式 | 說明 | 檔案指標 | 檔案存在 | 檔案不存在 | | -------- | ---- | ---- | -------| ---| | r | 讀取模式 | 檔案開頭 | | 錯誤 | | w | 寫入模式 | 檔案開頭 | 清除原有內容 | 建立檔案 | | a | 寫入模式 | 檔案結尾 | 附加到檔案後面 | 建立檔案 | | r+ | 讀寫模式 | 檔案開頭 | 覆蓋原有內容 | 錯誤 | | w+ | 讀寫模式 | 檔案開頭 | 清除原有內容 | 建立檔案 | | a+ | 讀寫模式 | 檔案結尾 | 附加到檔案後面 | 建立檔案 | | b | 二進位格式 | | | | ## 寫入檔案 ```python= userInfoFile = open(r"userinfo.txt", "w") userInfoFile.write("小明 男 1234567890\n") # \n表示換行 userInfoFile.write("小嫻 女 0123456789\n") userInfoFile.close() ``` ## 讀取檔案:讀取指定字數 f.read(n):讀取檔案n個英文字或n個中文字的內容 ```python= articleFile = open(r"userinfo.txt", "r") content = articleFile.read(6) # 只抓取6個文字 print(content) ``` **用vscode儲存會預設以UTF-8編碼中文字 ```python= articleFile = open(r"userinfo.txt", "r", encoding='utf-8') content = articleFile.read(6) # 只抓取6個文字 print(content) ``` **用「windows記事本」儲存會預設以big5編碼中文字 ```python= articleFile = open(r"big5_test.txt", "r", encoding='big5') content = articleFile.read(6) # 只抓取6個文字 print(content) ``` ## 移動n個位元 * 開啟檔案時必須以**二進位模式**開啟檔案 f.seek(n):檔案指標(file pointer)移動n個byte數 * f.seek(位移n個byte數,0) - 從文件開頭開始 * f.seek(位移n個byte數,1) - 從目前游標位置開始 * f.seek(位移n個byte數,2) - 從目前文件結尾開始 **英文文字:** ```python= articleFile = open(r"userinfo.txt", "rb") content = articleFile.read(2) # 只抓取2個文字 print(content) content = articleFile.read(2) # 只抓取2個文字 print(content) articleFile.seek(2, 0) content = articleFile.read(2) # 只抓取2個文字 print(content) articleFile.close() ``` **中文文字:** ```python= articleFile = open(r"article.txt", "rb+") content = articleFile.read(2*6) # 只抓取6個文字 print(str(content, 'big5')) articleFile.seek(2*6,1) content = articleFile.read(2*6) print(str(content, 'big5')) articleFile.close() ``` ## 讀取檔案:一次讀取一個段落的資料(直到遇到enter) ```python= articleFile = open(r"article.txt", "r") content = articleFile.readline() while content != '': print(content) content = articleFile.readline() articleFile.close() ``` ## 讀取檔案:讀取所有行並以list方式回傳資料 ```python= articleFile = open(r"article.txt", "r") content = articleFile.readlines() print(content) print(content[1]) # 顯示地2行的內容 for line in content: print(line) articleFile.close() ``` ## 檔案及資料夾管理 * exist: 檔案或資料夾是否存在 * isabs: 是否為檔案或資料夾的絕對路徑 * isdir: 是否為資料夾 * isfile: 是否為檔案 ```python= import os print(os.getcwd()) print('目前路徑位置 ', os.path.abspath('.')) print('目前路徑的上一層位置 ', os.path.abspath('..')) print('目前檔案的絕對路徑 ', os.path.abspath('test.py')) print('目前路徑到指定路徑的相對路徑 ', os.path.relpath('c:\\')) print('是否存在該資料夾或檔案 ', os.path.exists('testFolder')) print('testFolder是否為資料夾 ', os.path.isdir('testFolder')) print('test.py是否為檔案 ', os.path.isfile('test.py')) ``` * mkdir: 建立資料夾 * rmdir: 刪除資料夾,內部不能有檔案或資料夾 * remove: 刪除檔案 * chdir: 改變目前目錄位置 ```python= import os, shutil def show_menu(): print(""" 1. 顯示目前路徑 2. 進入指定路徑 3. 顯示目前路徑檔案及資料夾 4. 建立資料夾 5. 修改資料夾名稱 6. 刪除資料夾 E. 離開 """) return input("請根據所需功能輸入數字: ") if __name__ == '__main__': flag = True while flag: fun = show_menu() if fun == '1': print('目前路徑為: %s' % os.path.abspath('.')) elif fun == '2': path = input('請輸入要移到的路徑: ') os.chdir(path) print('目前路徑已改為: ', os.path.abspath('.')) elif fun == '3': for file in os.listdir('.'): print(' ', file) elif fun == '4': folder = input('請輸入要建立的資料夾名稱: ') os.mkdir(folder) elif fun == '5': old_name = input('請輸入要修改的資料夾名稱: ') new_name = input('請輸入要改成新的資料夾名稱: ') shutil.move(old_name, new_name) elif fun == '6': folder = input('請輸入要刪除的資料夾名稱: ') os.rmdir(folder) elif fun == 'e': flag = False ``` ## 建立資料夾 ```python= import os folder = input('請輸入要建立的資料夾名稱: ') os.mkdir(folder) print('資料夾 %s 成功' % folder) ``` ## 修改資料夾或檔案名稱 ```python= import shutil old_name = input('請輸入要修改的資料夾名稱: ') new_name = input('請輸入要改成新的資料夾名稱: ') shutil.move(old_name, new_name) print('資料夾 %s 已更改為 %s' % (old_name, new_name)) ``` ## 刪除資料夾 ```python= import os folder = input('請輸入要刪除的資料夾名稱: ') os.rmdir(folder) print('檔案 %s 刪除成功' % folder) ``` ## 刪除檔案 ```python= import os file = input('請輸入要刪除的檔案名稱: ') os.remove(file) print('檔案 %s 刪除成功' % file) ``` ## 連接路徑 ```python= import os path = os.path.join('c:\\', 'Users', 'Public', 'Music', 'Sample Music') print(path) os.chdir(path) for file in os.listdir('.'): print(' ', file) ``` ## 顯示資料夾底下所有子資料夾及檔案 參考資料:[Python 列出目錄中所有檔案教學:os.listdir 與 os.walk](https://blog.gtwang.org/programming/python-list-all-files-in-directory/) ```python= from os import walk mypath = input("請輸入要查詢的資料夾絕對路徑: ") # 指定要列出所有檔案的目錄 if not mypath: mypath = "/home/amos/正式區" # 遞迴列出所有子目錄與檔案 for root, dirs, files in walk(mypath): print("路徑:", root) print(" 目錄:", dirs) print(" 檔案:", files) ``` ## 完全複製來源資料夾到目標資料夾 ```python= import shutil from os import walk source_path = input("請輸入來源資料夾的絕對路徑: ") target_path = input("請輸入目標資料夾的絕對路徑: ") shutil.copytree(source_path, target_path) ``` ## 在指定目錄建立所有資料夾 ```python= import os folders = ['music', 'picture', 'doc', 'save'] base_path = input('請輸入專案路徑:') try: if not os.path.exists(base_path): os.mkdir(base_path) for folder in folders: path = os.path.join(base_path, folder) os.mkdir(path) except: print('專案資料夾建立錯誤') ``` ## 取得檔案大小 ```python= import os file = input('請輸入要查詢的檔案:') print('檔案 %s 大小為:%s bytes' % (file, os.path.getsize(file))) ``` ## 範例:讀寫密碼檔 ```python= class Software: def __init__(self): articleFile = open(r"id.acc", "r") content = articleFile.readlines() self.__name = content[0][:-1] self.__password = content[1] self.__article = None self.__logined = False self.__content = '' def login(self): name = input('請輸入帳號: ') password = input('請輸入密碼: ') if self.__name == name and self.__password == password: self.__logined = True print('you are login!', self.__logined) else: print('帳號或密碼錯誤,請重新輸入') def logout(self): self.__logined = False print('you are logout', self.__logined) def change_pw(self): if self.__logined: new_password = input('請輸入新密碼: ') new_password2 = input('請再輸入新密碼: ') if new_password == new_password2: self.__password = new_password userInfoFile = open(r"id.acc", "w") userInfoFile.write(self.__name + "\n") # \n表示換行 userInfoFile.write(self.__password) userInfoFile.close() print(self.__password) else: print('上下密碼不一致,請重新輸入') else: self.login() def post(self): if self.__logined: self.__content = input('請輸入文章內容: ') else: self.login() def read(self): if self.__logined: print(self.__content) else: self.login() mydictionary = Software() mydictionary.login() # mydictionary.logout() mydictionary.change_pw() # mydictionary.post() # mydictionary.read() ```