###### 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()
```