目標:
- 文件的概念
- 文件的基本操作
- 文件/文件夾的常用操作
- 文本文件的編碼方式
1.文件的概念
1.1文件的概念和作用
- 計算機的文件,就是存儲在某種長期存儲設備上的一段數據
- 長期存儲設備包括:硬盤、U盤、移動硬盤、光盤····
文件的作用:
將數據長期存儲下來,在需要的時候使用

1.2文件的存儲方式
- 在計算機中,文件是以 二進制 的方式保存在磁盤上的
文本文件和二進制文件
- 文本文件
- 可以用 文本編輯軟件查看
- 本質上還是二進制
- 例如:Python源文件
- 二進制文件
- 保存的內容不是給人直接閱讀的,而是提供給其他軟件使用的
- 例如:圖片文件、音頻文件、視頻文件等等
- 二進制文件不能直接使用文本編輯器查看
2.文件的基本操作
2.1操作文件的套路
在計算機中,要操作文件的套路非常固定,一共包含三個步驟:
- 打開文件
- 讀、寫文件
- 讀:將文件內容讀入內存
- 寫:將內存內容寫入文件
- 關閉文件
2.2操作文件的函數/方法
- 在Python中操作文件需要記住1個函數和3個方法
| 序號 | 函數/方法 | 說明 |
| 1 | open | 打開文件,並返回文件操作對象 |
| 2 | read | 將文件內容讀取到內存 |
| 3 | write | 將指定內容寫入到文件 |
| 4 | close | 關閉文件 |
- open() 函數負責打開文件,並返回文件對象
- read/write/close三個方法都需要通過文件對象來調用
2.3read方法——讀取文件
- open函數的第一個參數,是被打開的文件名(文件名區分大小寫)
- 如果文件存在,返回文件操作對象
- 如果文件不存在,會拋出異常
- read方法 可以一次性讀入並返回 文件的所有內容
- close方法 負責關閉文件
- 如果忘記關閉文件,會造成系統資源消耗,而且會影響到后續對文件的訪問
- 注意:方法執行后,會把文件指針移動到文件的末尾
- 提示:
- 在開發中,通常先編寫打開和關閉的代碼,在編寫中間針對文件讀/寫操作!
-
#獲得文件操作對象(sis.txt文件) file = open("sis.txt") #讀取 text = file.read() print(text) #關閉文件 file.close() ''' 運行結果 我是中文的哦 nidie中文 '''
- 文件指針
- 文件指針 標記 從那個位置開始讀取數據
- 第一次打開文件時,通常文件指針會指向文件開始的位置
- 當執行了read方法后,文件指針會移動到讀取內容的末尾
- 默認情況下會移動到文件末尾
- 思考:如果執行了一次read方法,讀取了所有內容,那么再次調用read方法還能獲取到內容嗎?
- 答案:不能。第一次讀取內容后,文件指針移動到文件末尾,再次調用不會讀取到任何內容
-
文件指針演示1 #獲得文件操作對象(sis.txt文件) 2 file = open("sis.txt") 3 #讀取 4 text = file.read() 5 #查看讀取文件的長度 (14) 6 print(len(text)) 7 #輸出讀取到的文件 8 print(text) 9 print("*"*30) 10 #重新讀取文件 11 text = file.read() 12 print(text) # 空 13 print(len(text)) # (0) 14 #關閉文件 15 file.close() 16 17 """ 18 運行結果: 19 14 20 我是中文的哦 21 nidie中文 22 ****************************** 23 24 0 25 """
2.4打開文件的方式
- open函數默認以只讀方式打開,並返回文件對象
語法如下:
-
- f = open( " 文件名 " , " 訪問方式 " )

-
x:以x打開一個文件,如果這個文件存在,那么報錯
- t:以t打開一個文件,底層是以二進制的形式打開,但是會默認幫我們將文件解碼(linux:默認以UTF-8).
- b:以b打開一個文件,是以二進制的形式打開,獲取到的信息都是字節。
-
r+、rt+、rb+,默認光標位置:起始位置 w+、wt+、wb+,默認光標位置:起始位置(清空文件) - x+、xt+、xb+,默認光標位置:起始位置(新文件) - a+、at+、ab+,默認光標位置:末尾
提示:頻繁的移動指針,會影響文件讀寫效率,開發中更多的時候會以 只讀、只寫 的方式來操作文件
2.5讀寫文件內容
-
-
f = open('info.txt', mode='r',encoding='utf-8') data = f.read() f.close() f = open('info.txt', mode='rb') data = f.read() f.close()
-
- 讀n個字符(字節)【會用到】
f = open('info.txt', mode='r', encoding='utf-8') # 讀1個字符 data = f.read(1) f.close() print(data) # 武 f = open('info.txt', mode='rb') # 讀1個字節 data = f.read(3) f.close() print(data, type(data)) # b'\xe6\xad\xa6' <class 'bytes'>
- read方法默認會把文件的 所有內容 一次性讀到內存
- 如果文件太大,對內存的占用會非常嚴重
readline 方法:
-
- 可以一次讀取一行內容
- 方法執行后,會把指針移動到下一行,准備再次讀取
讀取大文件的姿勢:
-
-
View Code1 #打開文件 2 file = open("sis.txt") 3 while True: 4 #讀取一行內容 5 text = file.readline() 6 #判斷是否讀取到內容 7 if text == "": #或者 if not text: 8 print(type(text)) #<class 'str'> 9 break 10 #每讀取到末尾都會有一個 \n 11 print(text,end="") 12 """ 13 運行結果: 14 python1一 15 python2二 16 python3三 17 python4四<class 'str'> 18 """
-
readlines,讀所有行,每行作為列表的一個元素
f = open('info.txt', mode='rb') data_list = f.readlines() f.close() print(data_list)
循環,讀大文件(readline加強版)【常見】
f = open('info.txt', mode='r', encoding='utf-8') for line in f: print(line.strip()) f.close()
write,寫
f = open('info.txt', mode='a',encoding='utf-8') f.write("你好") f.close() f = open('info.txt', mode='ab') f.write( "你好".encode("utf-8") ) f.close()
flush,刷到硬盤
f = open('info.txt', mode='a',encoding='utf-8') while True: # 不是寫到了硬盤,而是寫在緩沖區,系統會將緩沖區的內容刷到硬盤。 f.write("你好") f.flush() f.close()
移動光標位置(字節)
f = open('info.txt', mode='r+', encoding='utf-8') # 移動到指定字節的位置 f.seek(3) f.write("武沛齊") f.close()
移動到指定字節的位置,再插入數據時,會覆蓋后面的數據
注意:在a模式下,調用write在文件中寫入內容時,永遠只能將內容寫入到尾部,不會寫到光標的位置。
獲取當前光標位置(按字節算)
f = open('info.txt', mode='r', encoding='utf-8') p1 = f.tell() print(p1) # 0 f.read(3) # 讀3個字符 3*3=9字節 p2 = f.tell() print(p2) # 9 f.close() f = open('info.txt', mode='rb') p1 = f.tell() print(p1) # 0 f.read(3) # 讀3個字節 p2 = f.tell() print(p2) # 3 f.close()
2.6文件讀寫案例——復制文件
目標:用代碼實現文件的復制過程
- 小文件復制
- 打開一個已有文件,讀取完整內容,並寫入到另一個文件
-
小文件復制1 #復制小文件方式1 2 file_read = open("sis.txt","r") 3 file_write = open("test.txt","w") 4 text_1 = file_read.read() 5 text_2 = file_write.write(text_1) 6 file_write.close() 7 file_read.close() 8 9 #復制小文件方式2 推薦(with關鍵字,會自動釋放文件對象空間) 10 test = None 11 with open("sis.txt","r") as file: 12 test = file.read() 13 with open("test1.txt","w") as file: 14 file.write(test)
- 大文件復制
- 打開一個已有文件,逐行讀取內容,並順序寫入到另一個文件
-
大文件復制1 #大文件復制 2 file_read = open("五筆詞根1.jpg","rb") 3 file_write = open("五筆詞根2.jpg","wb") 4 while True: 5 text = file_read.readline() 6 #python中,除了‘’、""、0、()、[]、{}、None為False, 其他轉換都為True。 也就是說字符串如果不為空,則永遠轉換為True。 7 if not text: 8 break 9 file_write.write(text) 10 file_read.close() 11 file_write.close()
2.7上下文管理、文件讀寫中的函數
之前對文件進行操作時,每次都要打開和關閉文件,比較繁瑣且容易忘記關閉文件。
以后再進行文件操作時,推薦大家使用with上下文管理,它可以自動實現關閉文件。
with open("xxxx.txt", mode='rb') as file_object: data = file_object.read() print(data)
在Python 2.7 后,with又支持同時對多個文件的上下文進行管理,即:
with open("xxxx.txt", mode='rb') as f1, open("xxxx.txt", mode='rb') as f2: pass
文件讀取 — Python 3.10.1 文檔
3.文件/目錄的常用管理操作
- 在 終端/文件瀏覽 中可以執行常規的 文件/目錄 管理操作,例如
- 創建、重命名、刪除、改變路勁、查看目錄內容........
- 在Python中如果希望通過程序實現上述功能,需要導入 os 模塊
文件操作:

目錄操作:

- 提示:文件或者目錄操作,都支持 相對路徑 和 絕對路勁
4.文本文件的編碼方式
pass
# -*- coding: utf8 -*-
# -*- coding: utf-8 -*-
# -*- coding: gbk -*-
讀文件:
-
r打開文件,默認使用GBK(windows是默認GBK,但是MAC和linux是默認UTF-8)的編碼格式打開,所以在讀文件時,默認編碼需要與文件編碼相同否則報錯
-
rb打開文件,是一個字節流,所以需要decode()解碼,默認decode("utf-8")
-
rt打開,以文本的形式打開一個文件(默認使用(windows是默認GBK,但是MAC和linux是默認UTF-8)打開文件)
-
由上可知,python中的默認編碼是基於操作系統決定的 UTF-8:MAC、linux GBK:WIN
寫文件:
-
w打開文件,默認使用GBK(windows是默認GBK,但是MAC和linux是默認UTF-8)的編碼格式打開,所以在寫文件時,如果文件已存在並且該文件的默認編碼,與打開時的編碼不同,也會亂碼(因為它只會清空文件,不會修改文件的編碼格式)。在寫文件時,不需要encode。
-
wb打開二進制文件,不會受到編碼影響,在write寫入文件時,需要encode()壓縮,壓縮時指定編碼,那么生成的文件就是什么編碼。
-
所以:在打開一個文件時,最好指定其編碼格式,推薦為UTF-8
5.csv格式文件
逗號分隔值(Comma-Separated Values,CSV,有時也稱為字符分隔值,因為分隔字符也可以不是逗號),其文件以純文本形式存儲表格數據(數字和文本)。
對於這種格式的數據,我們需要利用open函數來讀取文件並根據逗號分隔的特點來進行處理。
CSV文件內容
練習題案例:下載文檔中的所有圖片且以用戶名為圖片名稱存儲。
import requests import os with open("test.txt", mode="r", encoding="utf-8") as read_f: read_f.readline() for line in read_f: user_id, name, url = line.strip().split(",") res = requests.get( url=url, headers={ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36" } ) if not os.path.exists("images"): #判斷文件夾是否存在,如果不存在,就創建 os.makedirs("images") with open("images/{}.png".format(name), mode="wb") as write_f: write_f.write(res.content)
6.ini格式文件
ini文件是Initialization File的縮寫,平時用於存儲軟件的的配置文件。例如:MySQL數據庫的配置文件。
[mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock log-bin=py-mysql-bin character-set-server=utf8 collation-server=utf8_general_ci log-error=/var/log/mysqld.log # Disabling symbolic-links is recommended to prevent assorted security risks symbolic-links=0 [mysqld_safe] log-error=/var/log/mariadb/mariadb.log pid-file=/var/run/mariadb/mariadb.pid [client] default-character-set=utf8
這種格式是可以直接使用open來出來,考慮到自己處理比較麻煩,所以Python為我們提供了更為方便的方式。configparser(配置解析器)
import configparser # 獲取可以處理ini文件的對象 config = configparser.ConfigParser() # 打開文件 config.read("test.ini", encoding="UTF-8") # 1.獲取所有節點 sections()(章節) result = config.sections() print(result) # 2.獲取節點下的鍵值 items(): 返回一個列表,列表中存儲鍵值對,鍵值對以元組的形式存儲 result = config.items("mysqld") print(result) for x, y in config.items("mysqld_safe"): # 可以使用這種方式將鍵值對取出 print(x, y) # 3.獲取節點下,鍵對應的值 get() result = config.get("mysqld", "datadir") print(result) # 4.檢測節點是否存在 has_section() result = config.has_section("mysqld") print(result) # 5.增加一個節點 add_section():如果節點已經存在,那么會報錯 config.add_section("root") # 6.給節點設置鍵值 set():節點必須存在,可創建鍵值對,也可修改值 config.set("root", "niha", "456") config.set("root", "niha1", "456") # 7.刪除節點 remove_section() :會刪除節點下的所有鍵值對 config.remove_section("root") # 8.刪除節點下的鍵值對 remove_option(節點,鍵) config.remove_option("root", "niha") # 4-8操作雖然給文件更改了數據,但是數據還在緩沖區中,所以在修改了文件后,需要使用write寫入 config.write(open('test.ini', 'w'))
5.拓展:eval函數
eval函數功能非常強大——將字符串當成有效的表達式來求值,並返回計算結果
# -*- coding: gbk -*- #基本的數學計算 print(eval("1+1")) #字符串重復 print(eval("'*'*30")) #將字符串轉變成列表 print(type(eval("[1,2,3,4,5]"))) #將字符串轉變成元組 print(type(eval("(1,2,3,4,5)"))) #將字符串轉變成字典 print(type(eval("{'name':'蘋果','age':18}")))
案例——計算器
input_str = input("輸入算數題") print(eval(input_str)) ''' 運行: 輸入算數題1+1 2 '''
注意:在開發的時候千萬不要使用 eval 直接轉換 input 的結果

