學(xué)習(xí)處理文件和保存數(shù)據(jù)可以使程序使用起來(lái)更容易,用戶將能夠選擇輸入什么樣的數(shù)據(jù), 以及在什么時(shí)候輸入; 用戶使用你的程序做一些工作后, 可將程序關(guān)閉, 以后再接著往下做。
從文件中讀取數(shù)據(jù)
文本文件可存儲(chǔ)的數(shù)據(jù)量多得難以置信: 天氣數(shù)據(jù)、 交通數(shù)據(jù)、 社會(huì)經(jīng)濟(jì)數(shù)據(jù)、 文學(xué)作品等。 每當(dāng)需要分析或修改存儲(chǔ)在文件中的信息時(shí), 讀取文件都很有用, 對(duì)數(shù)據(jù)分析應(yīng)用
程序來(lái)說(shuō)尤其如此。 例如, 你可以編寫一個(gè)這樣的程序: 讀取一個(gè)文本文件的內(nèi)容, 重新設(shè)置這些數(shù)據(jù)的格式并將其寫入文件, 讓瀏覽器能夠顯示這些內(nèi)容。
要使用文本文件中的信息, 首先需要將信息讀取到內(nèi)存中。 為此, 你可以一次性讀取文件的全部?jī)?nèi)容, 也可以以每次一行的方式逐步讀取。
不同模式打開(kāi)文件的完全列表:
模式描述
r ?以只讀方式打開(kāi)文件。文件的指針將會(huì)放在文件的開(kāi)頭。這是默認(rèn)模式。
rb ?以二進(jìn)制格式打開(kāi)一個(gè)文件用于只讀。文件指針將會(huì)放在文件的開(kāi)頭。這是默認(rèn)模式。
r+ ?打開(kāi)一個(gè)文件用于讀寫。文件指針將會(huì)放在文件的開(kāi)頭。
rb+ ?以二進(jìn)制格式打開(kāi)一個(gè)文件用于讀寫。文件指針將會(huì)放在文件的開(kāi)頭。
w ?打開(kāi)一個(gè)文件只用于寫入。如果該文件已存在則將其覆蓋。如果該文件不存在,創(chuàng)建新文件。
wb ?以二進(jìn)制格式打開(kāi)一個(gè)文件只用于寫入。如果該文件已存在則將其覆蓋。如果該文件不存在,創(chuàng)建新文件。
w+ ?打開(kāi)一個(gè)文件用于讀寫。如果該文件已存在則將其覆蓋。如果該文件不存在,創(chuàng)建新文件。
wb+ ?以二進(jìn)制格式打開(kāi)一個(gè)文件用于讀寫。如果該文件已存在則將其覆蓋。如果該文件不存在,創(chuàng)建新文件。
a ?打開(kāi)一個(gè)文件用于追加。如果該文件已存在,文件指針將會(huì)放在文件的結(jié)尾。也就是說(shuō),新的內(nèi)容將會(huì)被寫入到已有內(nèi)容之后。如果該文件不存在,創(chuàng)建新文件進(jìn)行寫入。
ab ?以二進(jìn)制格式打開(kāi)一個(gè)文件用于追加。如果該文件已存在,文件指針將會(huì)放在文件的結(jié)尾。也就是說(shuō),新的內(nèi)容將會(huì)被寫入到已有內(nèi)容之后。如果該文件不存在,創(chuàng)建新文件進(jìn)行寫入。
a+ ?打開(kāi)一個(gè)文件用于讀寫。如果該文件已存在,文件指針將會(huì)放在文件的結(jié)尾。文件打開(kāi)時(shí)會(huì)是追加模式。如果該文件不存在,創(chuàng)建新文件用于讀寫。
ab+ ?以二進(jìn)制格式打開(kāi)一個(gè)文件用于追加。如果該文件已存在,文件指針將會(huì)放在文件的結(jié)尾。如果該文件不存在,創(chuàng)建新文件用于讀寫。
1.1文件操作介紹
1.1.1什么是文件
1.1.2文件的作用
大家應(yīng)該聽(tīng)說(shuō)過(guò)一句話:“好記性不如爛筆頭”。
不僅人的大腦會(huì)遺忘事情,計(jì)算機(jī)也會(huì)如此,比如一個(gè)程序在運(yùn)行過(guò)程中用了九牛二虎之力終于計(jì)算出了結(jié)果,試想一下如果不把這些數(shù)據(jù)存放起來(lái),相比重啟電腦之后,“哭都沒(méi)地方哭了”
可見(jiàn),在把數(shù)據(jù)存儲(chǔ)起來(lái)有做么大的價(jià)值
使用文件的目的:
就是把一些存儲(chǔ)存放起來(lái),可以讓程序下一次執(zhí)行的時(shí)候直接使用,而不必重新制作一份,省時(shí)省力
1.2文件的打開(kāi)與關(guān)閉
想一想:
如果想用word編寫一份簡(jiǎn)歷,應(yīng)該有哪些流程呢?
1.打開(kāi)word軟件,新建一個(gè)word文件
2.寫入個(gè)人簡(jiǎn)歷信息
3.保存文件
4.關(guān)閉word軟件
同樣,在操作文件的整體過(guò)程與使用word編寫一份簡(jiǎn)歷的過(guò)程是很相似的
1.打開(kāi)文件,或者新建立一個(gè)文件
2.讀/寫數(shù)據(jù)
3.關(guān)閉文件
1.2.1打開(kāi)文件
在python,使用open函數(shù),可以打開(kāi)一個(gè)已經(jīng)存在的文件,或者創(chuàng)建一個(gè)新文件
open(文件名,訪問(wèn)模式)
示例如下:
f?=?open('test.txt','w')
說(shuō)明:
1.2.2關(guān)閉文件
close(?)
示例如下:
#新建一個(gè)文件,文件名為:test.txt
f?=?open('test.txt','w')
#關(guān)閉這個(gè)文件
f.close()
1.2.3路徑
1.2.3.1linux
1.2.3.2windows
1.3文件的讀寫
1.3.1寫數(shù)據(jù)(write)
使用write()可以完成向文件寫入數(shù)據(jù)
demo:
f?=?open('test.txt','w')
f.write('hello?world,?i?am?here!')
f.close()
注意:
·如果文件不存在那么創(chuàng)建,如果存在那么就先清空,然后寫入數(shù)據(jù)
1.3.2讀數(shù)據(jù)(read)
使用read(num)可以從文件中讀取數(shù)據(jù),num表示要從文件中讀取的數(shù)據(jù)的長(zhǎng)度(單位是字節(jié)),如果沒(méi)有傳入num,那么就表示讀取文件中所有的數(shù)據(jù)
demo:
f?=?open('test.txt','r')
content?=?f.read(5)
print(content)
print("-"*30)
content?=?f.read()
print(content)
f.close()
注意:
·如果open是打開(kāi)一個(gè)文件,那么可以不用謝打開(kāi)的模式,即只寫open('test.txt')
·如果使用讀了多次,那么后面讀取的數(shù)據(jù)是從上次讀完后的位置開(kāi)始的
1.3.3讀數(shù)據(jù)(readlines)
就像read沒(méi)有參數(shù)時(shí)一樣,readlines可以按照行的方式把整個(gè)文件中的內(nèi)容進(jìn)行一次性讀取,并且返回的是一個(gè)列表,其中每一行的數(shù)據(jù)為一個(gè)元素
f?=?open('test.txt','r')
content?=?f.readlines()
print(type(content))
i=1
fortempincontent:
print("%d:%s"%(i,?temp))
i+=1
f.close()
1.3.4讀數(shù)據(jù)(readline)
f?=?open('test.txt','r')
content?=?f.readline()
print("1:%s"%content)
content?=?f.readline()
print("2:%s"%content)
f.close()
想一想:
如果一個(gè)文件很大,比如5G,試想應(yīng)該怎樣把文件的數(shù)據(jù)讀取到內(nèi)存然后進(jìn)行處理呢?
1.4應(yīng)用1:制作文件的備份
任務(wù)描述:
輸入文件的名字,然后程序自動(dòng)完成對(duì)文件進(jìn)行備份
參考代碼:
oldFileName?=?input("請(qǐng)輸入要拷貝的文件名字:")
oldFile?=?open(oldFileName,'r')
#如果打開(kāi)文件
ifoldFile:
#提取文件的后綴
fileFlagNum?=?oldFileName.rfind('.')
iffileFlagNum?>0:
fileFlag?=?oldFileName[fileFlagNum:]
#組織新的文件名字
newFileName?=?oldFileName[:fileFlagNum]?+'[復(fù)件]'+?fileFlag
#創(chuàng)建新文件
newFile?=?open(newFileName,'w')
#把舊文件中的數(shù)據(jù),一行一行的進(jìn)行復(fù)制到新文件中
forlineContentinoldFile.readlines():
newFile.write(lineContent)
#關(guān)閉文件
oldFile.close()
newFile.close()
1.5文件的隨機(jī)讀寫
1.5.1獲取當(dāng)前讀寫的位置
在讀寫文件的過(guò)程中,如果想知道當(dāng)前的位置,可以使用tell()來(lái)獲取
從0開(kāi)始到字符的個(gè)數(shù)
#打開(kāi)一個(gè)已經(jīng)存在的文件
f?=?open("test.txt","r")
str?=?f.read(3)
print("讀取的數(shù)據(jù)是:?",?str)
#查找當(dāng)前位置
position?=?f.tell()
print("當(dāng)前文件位置:?",?position)
str?=?f.read(3)
print("讀取的數(shù)據(jù)是:?",?str)
#查找當(dāng)前位置
position?=?f.tell()
print("當(dāng)前文件位置:?",?position)
f.close()
1.5.2定位到某個(gè)位置
如果在讀寫文件的過(guò)程中,需要從另外一個(gè)位置進(jìn)行操作的話,可以使用seek()
seek(offset,?from)有2個(gè)參數(shù)
1.offset:偏移量
2.from:方向
a)0:表示文件開(kāi)頭(python3)
b)1:表示當(dāng)前位置(python2)
c)2:表示文件末尾(python2)
demo:把位置設(shè)置為:從文件開(kāi)頭,偏移5個(gè)字節(jié)
#打開(kāi)一個(gè)已經(jīng)存在的文件
f?=?open("test.txt","r")
str?=?f.read(30)
print("讀取的數(shù)據(jù)是:?",?str)
#查找當(dāng)前位置
position?=?f.tell()
print("當(dāng)前文件位置:?",?position)
#重新設(shè)置位置
f.seek(5,0)
#查找當(dāng)前位置
position?=?f.tell()
print("當(dāng)前文件位置:?",?position)
f.close()
demo:把位置設(shè)置為:離文件末尾,3字節(jié)處
#打開(kāi)一個(gè)已經(jīng)存在的文件
f?=?open("test.txt","r")
#查找當(dāng)前位置
position?=?f.tell()
print("當(dāng)前文件位置:?",?position)
#重新設(shè)置位置
f.seek(-3,2)
#讀取到的數(shù)據(jù)為:文件最后3個(gè)字節(jié)數(shù)據(jù)
str?=?f.read()
print("讀取的數(shù)據(jù)是:?",?str)
f.close()
1.6文件的重命名、刪除
有些時(shí)候,需要對(duì)文件進(jìn)行重命名、刪除等一些操作,python的os模塊中都有這么功能
1.6.1文件重命名
os模塊中的rename()可以完成對(duì)文件的重命名操作
rename(需要修改的文件名,新的文件名)
importos
os.rename("畢業(yè)論文.txt","畢業(yè)論文-最終版.txt")
1.6.2刪除文件
os模塊中的remove()可以完成對(duì)文件的刪除操作
remove(待刪除的文件名)
importos
os.remove("畢業(yè)論文.txt")
1.7文件夾的相關(guān)操作
實(shí)際開(kāi)發(fā)中,有時(shí)需要用程序的方式對(duì)文件夾進(jìn)行一定的操作,比如創(chuàng)建、刪除等
就像對(duì)文件操作需要os模塊一樣,如果要操作文件夾,同樣需要os模塊
1.7.1創(chuàng)建文件夾
importos
os.mkdir("張三")
os.makedirs(‘m/n’)
1.7.2獲取當(dāng)前目錄
importos
os.getcwd()
1.7.3改變默認(rèn)目錄
importos
os.chdir("../")
1.7.4獲取目錄列表
importos
os.listdir("./")
1.7.5刪除文件夾
importos
os.rmdir("張三")
import?shutil
os.rmtree(‘m’)
1.8應(yīng)用2:批量修改文件名
import?os
#得到完整路徑
dir?=?input('輸入完整的路徑:')
#獲取此路徑下的列表
all_file?=?os.listdir(dir)
#改變當(dāng)前的工作路徑
os.chdir(dir)
#遍歷
for?i?in?all_file:
#處理名字
new_name?=?i[:i.index('.')]?+?'-new'?+?i[i.index('.'):]
#重命名
os.rename(i,?new_name)