第 8 章 文件操作 (IO 技術)

簡介

文本文件和二進制文件

按文件中數據組織形式,我們把文件分爲文本文件和二進制文件兩大類:

1. 文本文件
		文本文件存儲的是普通“字符”文本,python默認爲unicode字符集(兩個字節表示 一個字符,
	最多可以表示:65536 個),可以使用記事本程序打開。但是,像word軟件編輯的文檔不是文
	本文件。 
2. 二進制文件
		二進制文件把數據內容用“字節”進行存儲,無法用記事本打開。必須使用專用的軟件 解碼。
	常見的有:MP4 視頻文件、MP3 音頻文件、JPG 圖片、doc 文檔等等。

文件操作相關模塊概述
在這裏插入圖片描述
創建文件對象 open()

	open()函數用於創建文件對象,基本語法格式如下: 
			open(文件名[,打開方式]) 
	如果只是文件名,代表在當前目錄下的文件。文件名可以錄入全路徑,比如:D:\a\b.txt。爲了減
少“\”的輸入,可以使用原始字符串:r“d:\b.txt”。示例如下: f = open(r"d:\b.txt","w")。

打開方式有如下幾種:
在這裏插入圖片描述
文本文件對象和二進制文件對象的創建:

	如果我們沒有增加模式“b”,則默認創建的是文本文件對象,處理的基本單元是“字符”。如果是
二進制模式“b”,則創建的是二進制文件對象,處理的基本單元是“字節”。

一、文本文件的寫入

1、基本的文件寫入操作

文本文件的寫入一般就是三個步驟:

	1. 創建文件對象 
	2. 寫入數據 
	3. 關閉文件對象

示例代碼:

# 文本寫入操作簡單測試
# 文本寫入操作簡單測試
file = open(r"E:\PythonProject\File_Test\file01.txt", "a")
info = '二哈撒的歡!!!'

file.write(info)
file.flush()
file.close()

2、常用編碼介紹

	在操作文本文件時,經常會操作中文,這時候就經常會碰到亂碼問題。爲了解決中文亂碼問題,
這裏簡單介紹一下各種編碼之間的關係。

常用編碼之間的關係如下:
在這裏插入圖片描述

1. ASCII
	全稱爲American Standard Code for Information Interchange,美國信息交換標準代碼,這是世界上
最早最通用的單字節編碼系統,主要用來顯示現代英語及其他西歐語言。 ASCII 碼用7位表示,只能表
示 128 個字符。只定義了2^7=128個字符,用7bit即可完全編碼,而一字節8bit的容量是256,所以一字
節ASCII 的編碼最高位總是0。
	0~31 表示控制字符如回車、退格、刪除等;
	32~126 表示打印字符即可以 通過鍵盤輸入並且能顯示出來的字符;
	其中 48~57 爲0到9十個阿拉伯數字;
	 65~90 爲 26 個大寫英文字母;
	 97~122 號爲26個小寫英文字母;
	 其餘爲一些標點符號、運算符號等,具體可以參考 ASCII 標準表。
2. ISO8859-1
	ISO-8859-1又稱Latin-1,是一個8位單字節字符集,它把ASCII的最高位也利用起來,併兼容了ASCII,
新增的空間是 128,但它並沒有完全用完。 在 ASCII 編碼之上又增加了西歐語言、希臘語、泰語、阿拉
伯語、希伯來語對應的文字符號,它是向下兼容 ASCII 編碼。
3. GB2312,GBK,GB18030

3.1:GB2312

	GB2312 全稱爲信息交換用漢字編碼字符集,是中國於 1980 年發佈,主要用於計算機系統中的漢字
處理。GB2312 主要收錄了 6763 個漢字、682 個符號。 GB2312覆蓋了漢字的大部分使用率,但不能
處理像古漢語等特殊的罕用字, 所以後來出現了像GBK、GB18030 這種編碼。
	**GB2312 完全兼容 ISO8859-1。**

3.2:GBK

	全稱爲 Chinese Internal Code Specification,即漢字內碼擴展規範,於 1995 年制定。 它主要是
擴展了 GB2312,在它的基礎上又加了更多的漢字,它一共收錄了 21003 個漢字

3.3:GB18030

	現在最新的內碼字集於 2000 年發佈,並於 2001 年強制執行,包含了中國大部分少數 民族的語言
字符,收錄漢字數超過 70000 餘個。 它主要採用單字節、雙字節、四字節對字符編碼,它是向下兼
容 GB2312 和 GBK 的, 雖然是我國的強制使用標準,但在實際生產中很少用到,用得最多的反而是
GBK 和 GB2312

3.4:Unicode

	Unicode 編碼設計成了固定兩個字節,所有的字符都用16 位(2^16=65536) 表示,包括之前只佔8
位的英文字符等,所以會造成空間的浪費,UNICODE 在 很長的一段時間內都沒有得到推廣應用。
	Unicode 完全重新設計,不兼容 iso8859-1,也不兼容任何其他編碼。

3.4:UTF-8

	對於英文字母,unicode 也需要兩個字節來表示。所以 unicode 不便於傳輸和存儲。因此而產生
了UTF編碼,UTF-8 全稱是(8-bit Unicode Transformation Format)。 UTF編碼兼容iso8859-1編
碼,同時也可以用來表示所有語言的字符, 不過,UTF 編碼是不定長編碼,每一個字符的長度從
1-4 個字節不等。其中, 英文字母都是用一個字節表示,而漢字使用三個字節。 

【老鳥建議】
		一般項目都會使用 UTF-8。unicode 中雖然漢字是兩個字節, UTF-8 中漢字是 3 個字節。
	但是互聯網中一個網頁也包含了大量的英文字母, 這些英文字母只佔用 1 個字節,整體佔用
	空間,UTF-8 仍然由於 Unicode。

中文亂碼問題

	windows 操作系統默認的編碼是 GBK,Linux操作系統默認的編碼是UTF-8。當我們用open()時,
調用的是操作系統打開的文件,默認的編碼是GBK。

3、write()/writelines()寫入數據

write(a):把字符串 a 寫入到文件中 
writelines(b):把字符串列表寫入文件中,不添加換行符

示例代碼:

# 添加字符串列表數據到文件中
file = open(r"E:\PythonProject\File_Test\file01.txt", "a")
info = ['姓名\n', '年齡\n', '職業\n']
file.writelines(info)
file.flush()
file.close()

4、close()關閉文件流

	由於文件底層是由操作系統控制,所以我們打開的文件對象必須顯式調用close()方法關閉文件
對象。當調用close()方法時,首先會把緩衝區數據寫入文件(也可以直接調用flush()方法),再關閉
文件,釋放文件對象。 爲了確保打開的文件對象正常關閉,一般結合異常機制的finally或者with關
鍵字實現無論何種情況都能關閉打開的文件對象。

示例代碼:

# 結合異常機制 finally 確保關閉文件對象
try:
    file = open(r"E:\PythonProject\File_Test\file01.txt", "a")
    info = ['姓名\n', '年齡\n', '職業\n']
    file.writelines(info)
except BaseException as e:
    print('異常信息:', e)
finally:
    file.flush()
    file.close()

# with 語句(上下文管理器)
# with 關鍵字(上下文管理器)可以自動管理上下文資源,不論什麼原因跳出with塊,都能確保
# 文件正確的關閉,並且可以在代碼塊執行完畢後自動還原進入該代碼塊時的現場。
# 使用 with 管理文件寫入操作
info2 = ['Jack\n', '20\n', 'IT\n']
with open(r"E:\PythonProject\File_Test\file01.txt", "a") as file2:
    file2.writelines(info2)

二、文本文件的讀取

文件的讀取一般使用如下三個方法:

	1. read([size]) 
		從文件中讀取 size 個字符,並作爲結果返回。如果沒有 size 參數,則讀取整個文件。 
	讀取到文件末尾,會返回空字符串。 
	2. readline() 
		讀取一行內容作爲結果返回。讀取到文件末尾,會返回空字符串。 
	3.  readlines() 
		文本文件中,每一行作爲一個字符串存入列表中,返回該列表

示例代碼:

'''源文件內容:
在Windows10系統右鍵點擊屏幕左下角的開始按鈕,在彈出菜單中選擇“運行”的菜單項。
然後在打開的Windows10運行窗口中輸入命令cmd後點擊確定按鈕
這時就會打開Windows10的命令提示符窗口,在這裏可以輸入Dos命令
首先在命令後面輸入d:按下回後後就可以快速切換到D盤分區
然後可以使用cd bdjy的命令,回車後就可以進入bdjy的文件夾了。
'''
# 讀取文件的前幾個字符
with open(r"E:\PythonProject\File_Test\file01.txt", "r", encoding="GBK") as file:
    print('讀取文件前幾個字符:', file.read(5))

# 文件較小,一次將文件內容讀入到程序中
with open(r"E:\PythonProject\File_Test\file01.txt", "r", encoding="GBK") as file:
    print('讀取文件整個內容:\n', file.read())

# 按行讀取一個文件
with open(r"E:\PythonProject\File_Test\file01.txt", "r", encoding="GBK") as file:
    while True:
        file_line = file.readline()
        if not file_line:
            break
        else:
            print('讀取文件一行內容:', file_line, end="")

# 使用迭代器按行讀取一個文件
with open(r"E:\PythonProject\File_Test\file01.txt", "r", encoding="GBK") as file:
    print('\n')
    for file_line in file:
        print('迭代器讀取文件一行內容:', file_line, end="")

# 爲文本文件每一行的行首增加一個行號
with open(r"E:\PythonProject\File_Test\file01.txt", "r", encoding="GBK") as file:
    file_lines = file.readlines()
    file_lines = [str(index + 1) + '. ' + line for index, line in enumerate(file_lines)]

with open(r"E:\PythonProject\File_Test\file01.txt", "w", encoding="GBK") as file:
    file.writelines(file_lines)
====================運行結果================================
讀取文件前幾個字符: 在Wind
讀取文件整個內容:
 在Windows10系統右鍵點擊屏幕左下角的開始按鈕,在彈出菜單中選擇“運行”的菜單項。
然後在打開的Windows10運行窗口中輸入命令cmd後點擊確定按鈕
這時就會打開Windows10的命令提示符窗口,在這裏可以輸入Dos命令
首先在命令後面輸入d:按下回後後就可以快速切換到D盤分區
然後可以使用cd bdjy的命令,回車後就可以進入bdjy的文件夾了。
讀取文件一行內容: 在Windows10系統右鍵點擊屏幕左下角的開始按鈕,在彈出菜單中選擇“運行”的菜單項。
讀取文件一行內容: 然後在打開的Windows10運行窗口中輸入命令cmd後點擊確定按鈕
讀取文件一行內容: 這時就會打開Windows10的命令提示符窗口,在這裏可以輸入Dos命令
讀取文件一行內容: 首先在命令後面輸入d:按下回後後就可以快速切換到D盤分區
讀取文件一行內容: 然後可以使用cd bdjy的命令,回車後就可以進入bdjy的文件夾了。

迭代器讀取文件一行內容: 在Windows10系統右鍵點擊屏幕左下角的開始按鈕,在彈出菜單中選擇“運行”的菜單項。
迭代器讀取文件一行內容: 然後在打開的Windows10運行窗口中輸入命令cmd後點擊確定按鈕
迭代器讀取文件一行內容: 這時就會打開Windows10的命令提示符窗口,在這裏可以輸入Dos命令
迭代器讀取文件一行內容: 首先在命令後面輸入d:按下回後後就可以快速切換到D盤分區
迭代器讀取文件一行內容: 然後可以使用cd bdjy的命令,回車後就可以進入bdjy的文件夾了。
====================運行結果================================

三、二進制文件的讀取和寫入

	二進制文件的處理流程和文本文件流程一致。首先還是要創建文件對象,不過,我們需要指
定二進制模式,從而創建出二進制文件對象。例如:
			f = open(r"d:\a.txt", 'wb')  #可寫的、重寫模式的二進制文件對象 
			f = open(r"d:\a.txt", 'ab')  #可寫的、追加模式的二進制文件對象 
			f = open(r"d:\a.txt", 'rb') #可讀的二進制文件對象 
	創建好二進制文件對象後,仍然可以使用 write()、read()實現文件的讀寫操作。

示例代碼:

# 讀取文本文件,實現文件的拷貝
with open(r"E:\PythonProject\File_Test\file01.txt", "rb") as file:
    with open(r"E:\PythonProject\File_Test\file01_bak.txt", "wb") as file2:
        for line in file.readlines():
            file2.write(line)
print('文件拷貝完成!!!')

四、文件對象的常用屬性和方法

文件對象的屬性

屬性 說明
name 返回文件的名字
mode 返回文件的打開模式
closed 若文件被關閉則返回 True

文件對象的打開模式

模式 說明
r 讀模式
w 寫模式
a 追加模式
b 二進制模式(可與其他模式組合)
+ 讀寫模式(可以其他模式組合)

文件對象的常用方法
在這裏插入圖片描述
在這裏插入圖片描述

五、文件任意位置操作

seek()移動文件指針示例

with open(r"E:\PythonProject\File_Test\file01.txt", "r", encoding="GBK") as file:
    print('文件名稱:{0}'.format(file.name))
    print('文件指針的當前位置:', file.tell())
    print('讀取的文件內容:{0}'.format(file.readline()))
    print('文件指針的當前位置:', file.tell())
    file.seek(83, 0)
    print('讀取的內容:{0}'.format(file.readline()))
====================運行結果================================
文件名稱:E:\PythonProject\File_Test\file01.txt
文件指針的當前位置: 0
讀取的文件內容:1. 在Windows10系統右鍵點擊屏幕左下角的開始按鈕,在彈出菜單中選擇“運行”的菜單項。

文件指針的當前位置: 83
讀取的內容:2. 然後在打開的Windows10運行窗口中輸入命令cmd後點擊確定按鈕
====================運行結果================================

六、使用 pickle 序列化

	Python 中,一切皆對象,對象本質上就是一個“存儲數據的內存塊”。有時候,我們 需要將“內存
塊的數據”保存到硬盤上,或者通過網絡傳輸到其他的計算機上。這時候,就需要“對象的序列化和
反序列化”。 對象的序列化機制廣泛的應用在分佈式、並行系統上。 
	序列化指的是:將對象轉化成“串行化”數據形式,存儲到硬盤或通過網絡傳輸到其他 地方。
	反序列化是指相反的過程,將讀取到的“串行化數據”轉化成對象。 
	我們可以使用 pickle 模塊中的函數,實現序列化和反序列操作。 
	
	**序列化使用:** 
		pickle.dump(obj, file)    # obj 就是要被序列化的對象,file 指的是存儲的文件 
		pickle.load(file)    # 從 file 讀取數據,反序列化成對象

示例代碼:

import pickle

# 將對象序列化到文件中
file_path = "E:\PythonProject\File_Test\\file01.txt"
with open(r"{0}".format(file_path), "wb") as file:
    msg1 = 'Jack'
    msg2 = '29'
    msg3 = 'IT'
    pickle.dump(msg1, file)
    pickle.dump(msg2, file)
    pickle.dump(msg3, file)

# 將獲得的數據反序列化成對象
with open(r"{0}".format(file_path), "rb") as file:
    info1 = pickle.load(file)
    info2 = pickle.load(file)
    info3 = pickle.load(file)

    print('{0} -- {1} -- {2}'.format(info1, info2, info3))
====================運行結果================================
Jack -- 29 -- IT
====================運行結果================================

七、CSV 文件的操作

	csv(Comma Separated Values)是逗號分隔符文本格式,常用於數據交換、Excel 文件和數據庫數據
的導入和導出。與 Excel 文件不同,CSV 文件中:
			值沒有類型,所有值都是字符串 
			不能指定字體顏色等樣式 
			不能指定單元格的寬高,
			不能合併單元格
			沒有多個工作表 
			不能嵌入圖像圖表

1、csv.reader 對象和 csv 文件讀取

示例代碼:

import csv

file_path = "E:\PythonProject\File_Test\\file02.csv"
with open(r"{0}".format(file_path)) as file:
    csv_obj = csv.reader(file)  # 創建csv對象,它是一個包含所有數據的列表,每一行爲一個元素
    headers = next(csv_obj)  # 獲得列表對象,包含標題行的信息
    print("headers:", headers)
    for row in csv_obj:
        print("row:", row)
====================運行結果================================
headers: ['name', 'age', 'job', 'sex', 'salary']
row: ['Jack', '22', 'IT', '男', '8000']
row: ['Leo', '24', '銷售', '女', '5000']
row: ['Marry', '28', '經理', '女', '16000']
====================運行結果================================

2、csv.writer 對象和 csv 文件寫入

示例代碼:

import csv

file_path = "E:\PythonProject\File_Test\\file02.csv"
header_info = ['id', 'name', 'class', 'score', 'sex']
row1 = ['001', '張三', '3班', '99', '男']
row2 = ['014', '李四', '6班', '70', '女']
row3 = ['023', 'Jack', '4班', '58', '男']
row4 = [('006', 'Leo', '2班', '83', '女'),
        ('008', 'Amy', '1班', '83', '女'),
        ('016', 'Seven', '3班', '83', '女')]

# 加上newline=''數據之間不會有空行
with open(r"{0}".format(file_path), "w", newline='') as file:  
    csv_obj = csv.writer(file)  # 創建CSV對象
    csv_obj.writerow(header_info)
    csv_obj.writerow(row1)
    csv_obj.writerow(row2)
    csv_obj.writerow(row3)
    csv_obj.writerows(row4)   # 寫入多行數據有加“s”的函數

八、os 和 os.path 模塊

	os 模塊可以幫助我們直接對操作系統進行操作。我們可以直接調用操作系統的可執行 文件、命令,
直接操作文件、目錄等等。是系統運維的核心基礎。

1、os 模塊-調用操作系統命令

os.system 可以幫助我們直接調用系統的命令
在這裏插入圖片描述
【注】Linux 是命令行操作更容易,我們可以通過 os.system 可以更加容易的調用相關的命 令;

2、os 模塊-文件和目錄操作

os 模塊下常用操作文件的方法
在這裏插入圖片描述

os 模塊下關於目錄操作的相關方法,彙總如下:
在這裏插入圖片描述

3、os.path 模塊

os.path 模塊提供了目錄相關(路徑判斷、路徑切分、路徑連接、文件夾遍歷)的操作

在這裏插入圖片描述
在這裏插入圖片描述

4、walk()遞歸遍歷所有文件和目錄

os.walk()方法:

返回一個 3 個元素的元組:(dirpath, dirnames, filenames) 
		dirpath:要列出指定目錄的路徑 
		dirnames:目錄下的所有文件夾 
		filenames:目錄下的所有文件

5、shutil 模塊(拷貝和壓縮)

	shutil模塊是python標準庫中提供的,主要用來做文件和文件夾的拷貝、移動、刪除等;
	還可以做 文件和文件夾的壓縮、解壓縮操作。 
	os模塊提供了對目錄或文件的一般操作。
	shutil 模塊作爲補充,提供了移動、複製、壓縮、解壓等操作,這些os模塊都沒有提供。

示例代碼:

import shutil
import zipfile

# copy文件內容
file_path = "E:\PythonProject\File_Test\\file02.csv"
file_path_bak = "E:\PythonProject\File_Test\\file02_bak.csv"
shutil.copy(file_path, file_path_bak)

# 實現遞歸的拷貝文件夾內容(使用 shutil 模塊)
file_dir = "E:\PythonProject\File_Test\學習文件"
new_dir = "E:\PythonProject\File_Test\\new_move"
# 此時new_move文件夾不存在時才成能功
shutil.copytree(file_dir, new_dir, ignore=shutil.ignore_patterns("*.csv"))

# 實現將文件夾所有內容壓縮(使用 shutil 模塊)
# 把“學習文件”壓縮到new_move文件夾下面(壓縮文件名:move.zip)
shutil.make_archive(new_dir + '\move', "zip", file_dir)  # 注意參數位置信息

# 壓縮:將指定的多個文件壓縮到一個 zip 文件
zip = zipfile.ZipFile(new_dir + "\\new.zip", "w")
file1 = "E:\PythonProject\File_Test\學習文件\\file01.txt"
file2 = "E:\PythonProject\File_Test\學習文件\\file02.csv"
zip.write(file1)
zip.write(file2)
zip.close()

# 解壓縮
unzip = zipfile.ZipFile(new_dir + "\move.zip", "r")
unzip.extractall(new_dir + "\\new_zip")   # 設置解壓的地址
unzip.close()

6、遞歸算法

	遞歸是一種常見的解決問題的方法,即把問題逐漸簡單化。遞歸的基本思想就是“自己 調用自己”,
一個使用遞歸技術的方法將會直接或者間接的調用自己。 利用遞歸可以用簡單的程序來解決一些復
雜的問題。比如:斐波那契數列的計算、漢諾 塔、快排等問題。

遞歸結構包括兩個部分:

定義遞歸頭:
	解答:什麼時候不調用自身方法。如果沒有頭,將陷入死循環,也就是遞歸的結束條件。
遞歸體:
	解答:什麼時候需要調用自身方法。

學習來自:北京尚學堂高琪老師 Python 400集

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章