# 【Python 筆記】檔案處理(File handling)
[TOC]
感謝您點進本篇文章,我是 LukeTseng,該系列主要以筆記加上口語白話形式學習 Python,若文章某處有誤敬請告知,非常感謝。
## 簡介
檔案處理是程式人必備的技能,主要是因為它能讓資料持久化,讓資訊存留在硬碟上,而非程式執行期間的記憶體中。也可以方便讀取或寫入資料檔,如設定檔、日誌(log)、或用戶資料。最重要的是自動化流程,例如可結合 .csv 套件將讀入的檔案寫入 .csv 中產生報表等等。
基本概念如下:
- 開檔(open):使用 `open()` 函數打開檔案。
- 讀寫(read / write):對檔案內容進行操作。
- 關檔(close):確保所有操作完成並釋放系統資源。
## open() 方法
使用 `open()` 之後,若沒有後續動作要執行,務必一定要搭配 `close()` 方法關閉檔案,不然你讓檔案一直在那邊開著浪費記憶體。
`open()` 基本語法:
```python
open(file, mode='r')
```
open 基本上是接收兩個參數,`file` 是檔名,而 mode 則是模式,可選擇讀(r)還是寫(w)。
而實際上 open 有很多參數可以調整,上述只是最基本的兩項:
```python
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
```
- buffering:設定緩衝區。
- encoding:設定編碼,如 utf-8、utf-16。
- errors:錯誤等級。
- newline:換行。
- closefd:傳入的 file 參數型態。
### 檔案開啟模式
| 模式 | 說明 |
| :-- | :-- |
| `r` | 讀取模式(預設)。若檔案不存在會報錯。 |
| `w` | 寫入模式。若檔案存在,會先清空內容。 |
| `a` | 附加模式。將內容寫到檔案末尾。 |
| `b` | 二進位模式,用於非文字檔案。 |
| `r+` | 同時讀與寫。檔案需存在。 |
| `w+` | 讀寫模式但會清空原檔案。 |
| `a+` | 讀寫模式但寫入追加在尾端。 |
### 範例
目錄架構有兩個檔案:`example.txt`、`main.py`,今天想要用 python 將 `example.txt` 的內容讀取並印出,可寫以下程式碼:
```python=
f = open('example.txt', 'r') # 打開檔案以讀取模式
content = f.read() # 讀取內容
print(content)
f.close() # 關閉檔案
```
`example.txt` 的內容如下:
```
Hello World! I like Python.
```
此程式會先開啟檔案、讀取,輸出內容,最後關閉檔案。
### 使用 with 敘述讀取檔案
with 是 Python 的一種資源管理器(Context manager),用來管理資源的取得與釋放。
它的主要用途是讓你在進入 block 的時候自動取得資源(如檔案),並在離開 block 時自動釋放資源,不論 block 內是否發生錯誤。
所以使用 with 的好處是 Python 都幫你做好資源管理了,也不用手動加上 `close()`。
基本語法如下:
```python
with obj as variable:
# 程式碼區塊 : block
xx = f.read()
print(xx)
# block 結束後,資源自動釋放
```
沿用上節範例:
```python=
with open('example.txt', 'r') as f:
content = f.read()
print(content)
```
同樣可讀取到 `Hello World! I like Python.`。
## 讀資料的方法
### read()
讀取整個檔案的內容。
語法:
```python
fileObject.read([size]);
```
fileObject 為檔案物件,而 `size` 為從 fileObject 中讀取的字元數,`size` 預設為 -1,表示讀取 fileObject 的整個內容。
以下是 `example.txt` 的內容:
```
Hello Python!
No C plus plus, I wanna Python.
ummmmm...... but Python's runtime speed is so slow.
```
範例:
```python=
with open('example.txt', 'r') as f:
line = f.read(9)
print(line)
```
Output:
```
Hello Pyt
```
### readline()
一次讀一行。
語法:
```python
fileObject.readline();
```
`example.txt` 內容:
```
Hello Python!
No C plus plus, I wanna Python.
ummmmm...... but Python's runtime speed is so slow.
abcabc
123123
456456
```
範例:
```python=
with open('example.txt', 'r') as f:
line1 = f.readline()
line2 = f.readline()
print(line1, line2, sep="")
```
### readlines()
讀取所有行並回傳成一個 list,碰到 EOF 會回傳空字串。
語法同 `readline()`。
`example.txt` 內容同上個範例。
範例:
```python=
with open('example.txt', 'r') as f:
for line in f.readlines():
line = line.strip() # 移除字串間的空格用
print(line)
```
## 寫入檔案
### write()
語法:
```python
fileObject.write( [ str ])
```
str:要寫入檔案的字串。
範例:
```python=
with open('example.txt', 'w') as f:
f.write('Hello Python!\n')
f.write('File handling is important.')
```
使用 `'w'` 模式會覆蓋掉檔案中所有內容。
執行後的 `example.txt`:
```
Hello Python!
File handling is important.
```
### writelines()
語法同 `write()`,只是在參數部分替換成字串列表或可迭代物件。
範例:
```python=
lines = ['Python\n', 'File\n', 'Handling\n']
with open('output.txt', 'w') as f:
f.writelines(lines)
```
執行後若沒有 `output.txt` 檔案則會自動生成,然後寫入三個字串:
```
Python
File
Handling
```
## 總整理
檔案處理是讓資料永久保存於硬碟(而非記憶體),常用於設定檔(config)、日誌(log)、自動化報表等。主要步驟包含:
- **開檔 (`open`)**:用 `open()` 打開檔案來準備讀/寫操作。
- **讀寫操作 (`read`/`write`)**:存取檔案內容。
- **關檔 (`close`)**:釋放系統資源,避免資源損耗。
### open 方法與模式
**基本語法**
```python
open(file, mode='r')
```
- `file`:檔案名稱
- `mode`:開檔模式(預設為 `'r'` 讀取)
**常用模式**
| 模式 | 功能說明 |
| :-- | :-- |
| `r` | 讀取(檔案需存在) |
| `w` | 寫入(會清空原內容或新建檔案) |
| `a` | 附加寫入(資料加在尾端) |
| `b` | 二進位模式(適合非文字檔) |
| `r+` | 讀寫(檔案需存在) |
| `w+` | 讀寫並清空檔案 |
| `a+` | 讀寫並追加在尾端 |
**開檔後務必記得關檔**,否則會浪費資源:
```python
f = open('example.txt', 'r')
content = f.read()
print(content)
f.close()
```
### 用 with 管理資源
用 `with` 區塊能自動管理開關檔案,不必手動 `close()`。
```python
with open('example.txt', 'r') as f:
content = f.read()
print(content)
# 出了區塊自動關檔
```
### read(size) 讀取指定字元數
```python
with open('example.txt', 'r') as f:
data = f.read(9)
print(data) # 只印出前9個字元
```
### readline() 讀取一行
```python
with open('example.txt', 'r') as f:
line1 = f.readline()
line2 = f.readline()
print(line1 + line2) # 連印兩行
```
### readlines() 讀取所有行,回傳 list
```python
with open('example.txt', 'r') as f:
for line in f.readlines():
print(line.strip()) # 去除行尾空白與換行
```
### write(str) 寫入文字
```python
with open('example.txt', 'w') as f:
f.write('Hello Python!\n')
f.write('File handling is important.')
# 會覆蓋原檔案內容
```
### writelines(list) 寫入多行文字
```python
lines = ['Python\n', 'File\n', 'Handling\n']
with open('output.txt', 'w') as f:
f.writelines(lines)
# 沒有檔案會自動生成
```
## 參考資料
[Python 寫檔,寫入 txt 文字檔 | ShengYu Talk](https://shengyu7697.github.io/python-write-text-file/)
[檔案操作 os - Python 教學 | STEAM 教育學習網](https://steam.oxxostudio.tw/category/python/library/os.html)
[Python 檔案處理:開啟、讀取、寫入與關閉 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天](https://ithelp.ithome.com.tw/articles/10368695)
[Python3 File 方法 | 菜鸟教程](https://www.runoob.com/python3/python3-file-methods.html)