標籤:cti 做了 資源 方法 類比 檔案開啟 作用 指定 記憶體回收
第1章 檔案處理1.1檔案操作流程
1、 開啟檔案,得到檔案控制代碼並賦值給一個變數
2、 通過控制代碼對檔案進行操作
3、 關閉檔案
1.2具體操作
1、開啟檔案,得到檔案控制代碼並賦值給一個變數
f=open(‘db.txt‘,‘r‘,encoding=‘utf-8‘)
2、通過控制代碼對檔案進行操作
data=f.read()
3、 關閉檔案
f.close() #回收作業系統資源
1.3流程分析
f=open(‘db.txt‘,‘r‘,encoding=‘utf-8‘)
1、由應用程式向作業系統發起系統調用:open(...)
2、作業系統開啟該檔案,並返回一個檔案控制代碼給應用程式
3、應用程式將檔案控制代碼賦值給變數f
1.4資源回收
1、 開啟一個檔案包含兩部分資源:
作業系統級開啟的檔案 和 應用程式的變數。
在操作完畢一個檔案時,必須把與該檔案的這兩部分資源一個不落地回收,方法是:
1) f.close() #回收作業系統級開啟的檔案;
2) del f #回收應用程式級的變數;python解譯器自動的記憶體回收機制已經替我們做了
注意:
1) del f 一定要發生在 f.close()之後,否則就會導致作業系統開啟的檔案沒有關閉,浪費資源,記住在操作完畢檔案後,一定要進行f.close
2) 開啟檔案的編碼是以作業系統的編碼為準的,除非open()指定encoding=‘編碼‘ )
1.5with 關鍵字
with的作用:上下文管理,它會幫我們來關閉檔案(f.close())
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) as f:
data=f.read()
### 支援同時管理多個檔案
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) as read_f,open(‘b.txt‘,‘r‘,encoding=‘utf-8‘) as write_f:
data=read_f.read()
write_f.write(data)
1.6字元編碼問題
f=open(...)是由作業系統開啟檔案,那麼如果我們沒有為open指定編碼,那麼開啟檔案的預設編碼很明顯是作業系統說了算了,作業系統會用自己的預設編碼去開啟檔案:
在windows下是gbk,在linux下是utf-8。
這就用到了上節課講的字元編碼的知識:若要保證不亂碼,檔案以什麼方式存的,就要以什麼方式開啟。
f=open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)
第2章 開啟檔案的模式
檔案控制代碼 = open(‘檔案路徑‘, ‘模式‘,‘字元編碼‘)
2.1文字模式(‘t‘,text mode(default)
r ,唯讀模式【預設模式,檔案必須存在,不存在則拋出異常】
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)as f:
print(f.read())
w,唯寫模式【不可讀;不存在則建立;存在則清空內容】
### 換行使用‘\n‘
with open(‘a.txt‘,‘w‘,encoding=‘utf-8‘) as f:
f.write(‘今天是2017.09.22\n‘)
f.write(‘今天是星期五\n‘)
今天是2017.09.22
今天是星期五
a, 只追加寫入模式【不可讀;不存在則建立;存在則只追加內容】
with open(‘a.txt‘,‘a‘,encoding=‘utf-8‘)as f:
f.write(‘111\n‘)
f.write(‘222\n‘)
f.write(‘333\n‘)
今天是2017.09.22
今天是星期五
111
222
333
2.2 二進位模式(‘b‘ binary mode)
對於非文字檔,我們只能使用b模式,"b"表示以位元組的方式操作(而所有檔案也都是以位元組的形式儲存的,使用這種模式無需考慮文字檔的字元編碼、圖片檔案的jgp格式、視頻檔案的avi格式)
註:以b方式開啟時,讀取到的內容是位元組類型,寫入時也需要提供位元組類型,不能指定編碼
with open(‘yuanhao.jpg‘,mode=‘rb‘) as f:
print(f.read())
### 如果對文本使用b二進位模式操作,記得要解碼成utf-8
with open(‘a.txt‘,mode=‘rb‘) as f:
data=f.read()
print(data.decode(‘utf-8‘))
### 寫入文字格式設定的話,需要encode utf-8
with open(‘d.txt‘,mode=‘wb‘) as f:
f.write(‘哈哈哈hello‘.encode(‘utf-8‘))
2.3瞭解模式
"+" 表示可以同時讀寫某個檔案
r+, 讀寫【可讀,可寫】
w+,寫讀【可讀,可寫】
a+, 寫讀【可讀,可寫】
x, 唯寫模式【不可讀;不存在則建立,存在則報錯】
x+ ,寫讀【可讀,可寫】
第3章 操作檔案的方法3.1掌握 3.1.1read (讀取)
f.read() #讀取所有內容,游標移動到檔案末尾
f.readline()#讀取一行內容,游標移動到第二行首部
f.readlines() #讀取每一行內容,存放於列表中
### 讀取所有內容,檔案大的時候不要用 read
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)as f_read:
print(f_read.read())
今天是2017.09.22
今天是星期五
111
222
333
### 按行讀取內容
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)as f_read:
print(f_read.readline())
print(f_read.readline())
今天是2017.09.22
今天是星期五
### 需要加上end=‘‘用來替換掉換行的 \n
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)as f_read:
print(f_read.readline(),end=‘‘) #一次讀一行
print(f_read.readline(),end=‘‘)
今天是2017.09.22
今天是星期五
### 讀所有,結果放入列表中
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)as f_read:
print(f_read.readlines()) #讀所有,大檔案的話會很卡
[‘今天是2017.09.22\n‘, ‘今天是星期五\n‘, ‘111\n‘, ‘222\n‘, ‘333\n‘]
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)as f_read:
print(f_read.readlines()[0])
今天是2017.09.22
3.1.2write (寫入)
f.write(‘1111\n222\n‘) #針對文字模式的寫,需要自己寫分行符號
f.write(‘1111\n222\n‘.encode(‘utf-8‘)) #針對b模式的寫,需要自己寫分行符號
f.writelines([‘333\n‘,‘444\n‘]) #檔案模式
f.writelines([bytes(‘333\n‘,encoding=‘utf-8‘),‘444\n‘.encode(‘utf-8‘)]) #b模式
將列表中的內容寫入檔案:
l=[‘444\n‘,‘555\n‘,‘666\n‘]
with open(‘a.txt‘,‘a‘,encoding=‘utf-8‘)as f_write:
for linein l:
f_write.write(line)
今天是2017.09.22
今天是星期五
111
222
333
444
555
666
### 使用writeline方法
with open(‘a.txt‘,‘a‘,encoding=‘utf-8‘)as f_write:
f_write.writelines([‘444\n‘,‘555\n‘,‘666\n‘])
3.1.3
#遍曆檔案z
with open(‘a.txt‘,encoding=‘utf-8‘) as f:
#不推薦使用
# lines=f.readlines()
# for line in lines:
# print(line,end=‘‘)
### 推薦使用
for line in f:
print(line,end=‘‘)
3.2瞭解
f.readable() #檔案是否可讀
f.writable() #檔案是否可讀
f.closed #檔案是否關閉
f.encoding #如果檔案開啟模式為b,則沒有該屬性
f.flush() #立刻將檔案內容從記憶體刷到硬碟
第4章 檔案操作的其他方法4.1read(n)
### 以文本的模式讀檔案,n代表的是字元的個數
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)as f:
data=f.read(3)
print(data)
今天是
### 以b的模式讀檔案,n代表的是位元組的個數
with open(‘a.txt‘,‘rb‘)as f:
data=f.read(3)
print(f.tell())
print(data.decode(‘utf-8‘))
3
今
4.2tell 返回游標位置
### tell:告訴當前游標的位置
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)as f:
data=f.read(3)
print(f.tell())
print(data)
9
今天是
4.3seek 移動游標
fileObject.seek(offset[, whence])
offset -- 開始的位移量,也就是代表需要移動位移的位元組數
whence:可選,預設值為 0。給offset參數一個定義,表示要從哪個位置開始位移;0代表從檔案開頭開始算起,1代表從當前位置開始算起,2代表從檔案末尾算起。
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘)as f:
data1=f.read()
print(‘first: ‘,data1)
print(f.tell())#擷取當前游標位置
f.seek(0) #移動到檔案開頭
data2 = f.read() #由於游標移動到檔案開頭,所以檔案又完全輸出一次
print(‘second: ‘,data2)
first: abc
efd
12
second: abc
efd
第5章 檔案的修改
檔案的資料是存放於硬碟上的,因而只存在覆蓋、不存在修改這麼一說,我們平時看到的修改檔案,都是類比出來的效果,具體的說有兩種實現方式:
方式一:將硬碟存放的該檔案的內容全部載入到記憶體,在記憶體中是可以修改的,修改完畢後,再由記憶體覆蓋到硬碟(word,vim,nodpad++等編輯器)
e.txt >>>
alex say i have on tesla
my name is alex
alex is good
alex xxxx hahaha alex
### 方式一(佔用記憶體過大,僅適用於小檔案):把硬碟中檔案的資料全部讀入記憶體,然後在記憶體裡進行修改,最後儲存
import os
with open(‘e.txt‘,‘r‘,encoding=‘utf-8‘)as f_read,\
open(‘.e.txt.swap‘,‘w‘,encoding=‘utf-8‘)as f_write:
data=f_read.read()
data=data.replace(‘alex‘,‘sb‘)
f_write.write(data)
os.remove(‘e.txt‘)
os.rename(‘.e.txt.swap‘,‘e.txt‘)
### 方式二:一行一行地讀,一行一行地改
import os
with open(‘e.txt‘,‘r‘,encoding=‘utf-8‘)as f_read ,open(‘e.txt.swap‘,‘w‘,encoding=‘utf-8‘)as f_write:
for nin f_read:
data=n.replace(‘sb‘,‘alex‘) ### 讀一行
f_write.write(data) ### 改一行
os.remove(‘e.txt‘)
os.rename(‘e.txt.swap‘,‘e.txt‘)
第6章 把檔案檔資料庫
db.txt>>>
1,peigen1,38,male,1234563378
2,peigen2,28,female,1234335678
3,peigen3,18,male,123145678
4,peigen4,8,male,1234115678
5,peigen5,48,female,1232245678
6,peigen6,58,male,1234335678
with open(‘db.txt‘,‘r‘,encoding=‘utf-8‘)as f:
for linein f:
user_l=line.split(‘,‘)
print(user_l[1],int(user_l[2]))
peigen1 38
peigen2 28
peigen3 18
peigen4 8
peigen5 48
peigen6 58
第四章 Python 檔案處理