1. 程式人生 > >第四章 Python 文件處理

第四章 Python 文件處理

定義 包含 文本文件 讀寫 時也 導致 linu 文件 無需

第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.5 with 關鍵字

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.1 read (讀取)

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.2 write (寫入)

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 line in 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.1 read(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.2 tell 返回光標位置

### tell:告訴當前光標的位置
with open(‘a.txt‘,‘r‘,encoding=‘utf-8‘) as f:
data=f.read(3)
print(f.tell())
print(data)

9

今天是

4.3 seek 移動光標

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 n in 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 line in 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 文件處理