# 檔案操作

## 列出檔案目錄

在操作檔案之前，可以先使用以下的命令來列出目前的目錄中所有的檔案列表：

```
>>> import os
>>> os.listdir()
['.ipynb_checkpoints', 'Chapter02.ipynb']
```

os.listdir()會傳回一個串列，其中就包含了所有目前中的檔案，想要顯示目前的檔案數量，只要如前面在介紹串列的操作中所使用的len函數一樣，透過 len來計算串列的長度，就等於是知道了目前目錄中的檔案數量。

```
>>> import os
>>> os.listdir()
['.ipynb_checkpoints', 'Chapter02.ipynb']
>>> n = len(os.listdir())
>>> print("There are {} files in this directory!".format(n))
There are 2 files in this directory!
```

## 建立資料夾&#x20;

os模組除了列出檔案名稱之外，也可以透遇mkdir來建立資料夾，操作如下：

```
>>> os.mkdir("data")
>>> os.listdir()
['.ipynb_checkpoints', 'Chapter02.ipynb', 'data']
```

## 寫入檔案

要寫入檔案需要先指定檔案名稱，然後執行開始檔案，再把開啟後的結果放在一個變數物件中，之後就可以透過該指標對這個檔案進行存取，結束不使用之後再把檔案關閉即可。以下是一個開啟檔案，寫入一個字串之後再把檔案關閉的程式範例：

```python
>>> fp = open("mydata.txt", "wt")
>>> fp.write("This is my data!\n")
17
>>> fp.close()
>>> os.listdir()
['.ipynb_checkpoints', 'Chapter02.ipynb', 'data', 'mydata.txt']
```

{% hint style="warning" %}
請注意，在第2行的字串中最後面那個「\n」的符號是換行記號，沒有這行的話，後面的資料會被串接在這一行的後面。
{% endhint %}

在開啟檔案的時候，檔案名稱後面那個參數就是用來指定要對檔案存取的方式，有以下幾種可用的指示元：

| mode | 說明       |
| ---- | -------- |
| r    | 讀取       |
| a    | 附加資料到檔案中 |
| w    | 寫入       |
| x    | 建立檔案     |

其中，如果w和a最大的差別在於是否需要保留原有檔案中的資料，如果使用w的話，會把原有的檔案資料清掉重寫，而a則會讓新的資料附加在原有的資料的後面。以下的例子是使用a來開啟之前的檔案，再寫入一些資料的例子：

```python
>>> fp = open("mydata.txt", "a")
>>> fp.write("This is 2nd line!\n")
18
>>> fp.close()
```

在上面的4個指字元之後還可以再選擇以下的兩種其中之一，特別說明要存取的資料是何種型式：

| 模式 | 說明                              |
| -- | ------------------------------- |
| t  | 文字模式，這也是預設的模式                   |
| b  | 二進位模式，主要是為了處理非可讀取的二進元檔案，如圖形檔等格式 |

一般來說我們都只要使用預設的模式，以文字檔的方式來存取資料就可以了。

## 從檔案中讀取資料

在前述的程式中寫入的文字資料，要如何才能夠把它讀取出來呢？同樣也是使用open函數開啟檔案，在取得檔案物件之後，就可以利用read, readline, readlines來讀取檔案中的資料，此三個函數主要的差異在如下表所列：

| 函數名稱      | 說明                                |
| --------- | --------------------------------- |
| read      | 一次讀取檔案中的所有資料                      |
| readline  | 一次讀取檔案中的一行資料                      |
| readlines | 一次讀取檔案中的資料，但是把資料分成一列列，逐列放到串列資料結構中 |

以下的程式是把之前的檔案都讀取出來之後的比較：

```python
fp = open("mydata.txt")
print(fp.read())
fp.seek(0)
print(fp.readline())
fp.seek(0)
print(fp.readlines())
fp.close()
```

{% hint style="info" %}
第3行、第5行的seek是用來調整目前要讀取的資料的指標位置用的，seek(0)就表示要回到檔案的最前面。
{% endhint %}

以下是程式輸出的結果：

```
This is my data!
This is 2nd line!

This is my data!

['This is my data!\n', 'This is 2nd line!\n']
```

同學們可以看得出來差別了嗎？

## with的用法

因為每一次使用檔案都要開檔和關檔，如果這個檔案打開之後只做了一些事就要關檔，並不會在其它的地方繼續使用的話，使用with可以簡化一些程序，也避免檔案打開之後就忘記關閉的情形，前面的程式如果使用with的話，可以改寫如下：

```python
with open("mydata.txt") as fp:
	print(fp.read())
	fp.seek(0)
	print(fp.readline())
	fp.seek(0)
	print(fp.readlines())
```

改完之後功能是一樣的喔。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://nkust.gitbook.io/python/an-cao-zuo-fang-fa.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
