五月综合缴情婷婷六月,色94色欧美sute亚洲线路二,日韩制服国产精品一区,色噜噜一区二区三区,香港三级午夜理伦三级三

您現(xiàn)在的位置: 365建站網(wǎng) > 365文章 > Python中IO編程(文件讀寫,操作文件和目錄,序列化操作)

Python中IO編程(文件讀寫,操作文件和目錄,序列化操作)

文章來源:365jz.com     點擊數(shù):289    更新時間:2018-01-16 11:50   參與評論
IO編程

IO在計算機中指的是Input/Output,也就是輸入輸出。凡是用到數(shù)據(jù)交換的地方,都會涉及IO編程,例如磁盤、網(wǎng)絡(luò)的數(shù)據(jù)傳輸。在IO編程中,Stream(流)是一種重要的概念,分為輸入流(Input Stream)和輸出流(Output Stream)。我們可以把流理解為一個水管,數(shù)據(jù)相當(dāng)于水管中的水,但是只能單向流動,所以數(shù)據(jù)傳輸過程中需要架設(shè)兩個水管,一個負(fù)責(zé)輸入,一個負(fù)責(zé)輸出,這樣讀寫就可以實現(xiàn)同步。

文件讀寫


1.打開文件

讀寫文件是最常見的IO操作。Python內(nèi)置了讀寫文件的函數(shù),方便了文件的IO操作。

文件讀寫之前需要打開文件,確定文件的讀寫模式。open函數(shù)用來打開文件,語法如下:

open(name[.mode[.buffering]])


open函數(shù)使用一個文件名作為唯一的強制參數(shù),然后返回一個文件對象。模式(mode)和緩沖區(qū)(buffering)參數(shù)都是可選的,默認(rèn)模式是讀模式,默認(rèn)緩沖區(qū)是無。

假設(shè)有個名為qiye.txt的文本文件,其存儲路徑是c:\text(或者是在Linux下的~/text),那么可以像下面這樣打開文件。在交互式環(huán)境的提示符“>>>”下,輸入如下內(nèi)容:

>>> f = open(r'c:\text\qiye.txt')

如果文件不存在,將會看到一個類似下面的異?;厮荩?/p>

Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IOError: [Errno 2] No such file or directory: 'C:\\qiye.txt'



2.文件模式

下面主要說一下open函數(shù)中的mode參數(shù)(如表11所示),通過改變mode參數(shù)可以實現(xiàn)對文件的不同操作。

表11 open函數(shù)中的mode參數(shù)

這里主要是提醒一下‘b’參數(shù)的使用,一般處理文本文件時,是用不到‘b’參數(shù)的,但處理一些其他類型的文件(二進制文件),比如mp3音樂或者圖像,那么應(yīng)該在模式參數(shù)中增加‘b’,這在爬蟲中處理媒體文件很常用。參數(shù)‘rb’可以用來讀取一個二進制文件。


3.文件緩沖區(qū)

open函數(shù)中第三個可選參數(shù)buffering控制著文件的緩沖。如果參數(shù)是0,I/O操作就是無緩沖的,直接將數(shù)據(jù)寫到硬盤上;如果參數(shù)是1,I/O操作就是有緩沖的,數(shù)據(jù)先寫到內(nèi)存里,只有使用flush函數(shù)或

者close函數(shù)才會將數(shù)據(jù)更新到硬盤;如果參數(shù)為大于1的數(shù)字則代表緩沖區(qū)的大?。▎挝皇亲止?jié)),1(或者是任何負(fù)數(shù))代表使用默認(rèn)緩沖區(qū)的大小。


4.文件讀取文件

讀取主要是分為按字節(jié)讀取和按行進行讀取,經(jīng)常用到的方法有read()、readlines()、close()。

在“>>>”輸入f=open(r‘c:\text\qiye.txt’)后,如果成功打開文本文件,接下來調(diào)用read()方法則可以一次性將文件內(nèi)容全部讀到內(nèi)存中,最后返回的是str類型的對象:

>>> f.read()
"qiye"


最后一步調(diào)用close(),可以關(guān)閉對文件的引用。文件使用完畢后必須關(guān)閉,因為文件對象會占用操作系統(tǒng)資源,影響系統(tǒng)的IO操作。

>>> f.close()


由于文件操作可能會出現(xiàn)IO異常,一旦出現(xiàn)IO異常,后面的close()方法就不會調(diào)用。所以為了保證程序的健壯性,我們需要使用try...finally來實現(xiàn)。

try:
f = open(r'c:\text\qiye.txt','r')
print f.read()
finally:
if f:
f.close()


上面的代碼略長,Python提供了一種簡單的寫法,使用with語句來替代try...finally代碼塊和close()方法,如下所示:

with open(r'c:\text\qiye.txt','r') as fileReader:
print fileReader.read()


調(diào)用read()一次將文件內(nèi)容讀到內(nèi)存,但是如果文件過大,將會出現(xiàn)內(nèi)存不足的問題。一般對于大文件,可以反復(fù)調(diào)用read(size)方法,一次最多讀取size個字節(jié)。如果文件是文本文件,Python提供了更加合理的做法,調(diào)用readline()可以每次讀取一行內(nèi)容,調(diào)用readlines()一次讀取所有內(nèi)容并按行返回列表。大家可以根據(jù)自己的具體需求采取不同的讀取方式,例如小文件可以直接采取read()方法讀到內(nèi)存,大文件更加安全的方式是連續(xù)調(diào)用read(size),而對于配置文件等文本文件,使用readline()方法更加合理。

將上面的代碼進行修改,采用readline()的方式實現(xiàn)如下所示:

with open(r'c:\text\qiye.txt','r') as fileReader:
for line in fileReader.readlines():
print line.strip()


5.文件寫入

寫文件和讀文件是一樣的,唯一的區(qū)別是在調(diào)用open方法時,傳入標(biāo)識符‘w’或者‘wb’表示寫入文本文件或者寫入二進制文件,示例如下:

f = open(r'c:\text\qiye.txt','w')
f.write('qiye') f.close()

我們可以反復(fù)調(diào)用write()方法寫入文件,最后必須使用close()方法來關(guān)閉文件。使用write()方法的時候,操作系統(tǒng)不是立即將數(shù)據(jù)寫入文件中的,而是先寫入內(nèi)存中緩存起來,等到空閑時候再寫入文件中,最后使用close()方法就將數(shù)據(jù)完整地寫入文件中了。當(dāng)然也可以使用f.flush()方法,不斷將數(shù)據(jù)立即寫入文件中,最后使用close()方法來關(guān)閉文件。和讀文件同樣道理,文件操作中可能會出現(xiàn)IO異常,所以還是推薦使用with語句:

with open(r'c:\text\qiye.txt','w') as fileWriter:
fileWriter.write('qiye')


操作文件和目錄

在Python中對文件和目錄的操作經(jīng)常用到os模塊和shutil模塊。

接下來主要介紹一些操作文件和目錄的常用方法:·獲得當(dāng)前Python腳本工作的目錄路徑:os.getcwd()。

·返回指定目錄下的所有文件和目錄名:os.listdir()。例如返回C盤下的文件:os.listdir(“C:\\”)·刪除一個文件:os.remove(filepath)。

·刪除多個空目錄:os.removedirs(r“d:\python”)。

·檢驗給出的路徑是否是一個文件:os.path.isfile(filepath)。

·檢驗給出的路徑是否是一個目錄:os.path.isdir(filepath)。

·判斷是否是絕對路徑:os.path.isabs()。

·檢驗路徑是否真的存在:os.path.exists()。例如檢測D盤下是否有Python文件夾:os.path.exists(r“d:\python”)·分離一個路徑的目錄名和文件名:os.path.split()。例如:·os.path.split(r“/home/qiye/qiye.txt”),返回結(jié)果是一個元組:(‘/home/qiye’,‘qiye.txt’)。

·分離擴展名:os.path.splitext()。例如os.path.splitext(r“/home/qiye/qiye.txt”),返回結(jié)果是一個元組:(‘/home/qiye/qiye’,‘.txt’)。

·獲取路徑名:os.path.dirname(filepah)。

·獲取文件名:os.path.basename(filepath)。

·讀取和設(shè)置環(huán)境變量:os.getenv()與os.putenv()。

·給出當(dāng)前平臺使用的行終止符:os.linesep。Windows使用‘\r\n’,Linux使用‘\n’而Mac使用‘\r’。

·指示你正在使用的平臺:os.name。對于Windows,它是‘nt’,而對于Linux/Unix用戶,它是‘posix’。

·重命名文件或者目錄:os.rename(old,new)。

·創(chuàng)建多級目錄:os.makedirs(r“c:\python\test”)。

·創(chuàng)建單個目錄:os.mkdir(“test”)。

·獲取文件屬性:os.stat(file)。

·修改文件權(quán)限與時間戳:os.chmod(file)。

·獲取文件大小:os.path.getsize(filename)。

·復(fù)制文件夾:shutil.copytree(“olddir”,“newdir”)。olddir和newdir都只能是目錄,且newdir必須不存在。

·復(fù)制文件:shutil.copyfile(“oldfile”,“newfile”),oldfile和

newfile都只能是文件;shutil.copy(“oldfile”,“newfile”),oldfile只能是文件,newfile可以是文件,也可以是目標(biāo)目錄。

·移動文件(目錄):shutil.move(“oldpos”,“newpos”)。

·刪除目錄:os.rmdir(“dir”),只能刪除空目錄;shutil.rmtree(“dir”),空目錄、有內(nèi)容的目錄都可以刪。


序列化操作

對象的序列化在很多高級編程語言中都有相應(yīng)的實現(xiàn),Python也不例外。程序運行時,所有的變量都是在內(nèi)存中的,例如在程序中聲明一個dict對象,里面存儲著爬取的頁面的鏈接、頁面的標(biāo)題、頁面的摘要等信息:

d = dict(url='index.html',title='首頁',content='首頁')

在程序運行的過程中爬取的頁面的鏈接會不斷變化,比如把url改成了second.html,但是程序一結(jié)束或意外中斷,程序中的內(nèi)存變量都會被操作系統(tǒng)進行回收。如果沒有把修改過的url存儲起來,下次運行程序的時候,url被初始化為index.html,又是從首頁開始,這是我們不愿意看到的。所以把內(nèi)存中的變量變成可存儲或可傳輸?shù)倪^程,就是序列化。

將內(nèi)存中的變量序列化之后,可以把序列化后的內(nèi)容寫入磁盤,或者通過網(wǎng)絡(luò)傳輸?shù)絼e的機器上,實現(xiàn)程序狀態(tài)的保存和共享。反過來,把變量內(nèi)容從序列化的對象重新讀取到內(nèi)存,稱為反序列化。

在Python中提供了兩個模塊:cPickle和pickle來實現(xiàn)序列化,前者是由C語言編寫的,效率比后者高很多,但是兩個模塊的功能是一樣的。一般編寫程序的時候,采取的方案是先導(dǎo)入cPickle模塊,如果此模塊不存在,再導(dǎo)入pickle模塊。示例如下:
 

try:
import cPickle as pickle
except ImportError:
import picklepickle

實現(xiàn)序列化主要使用的是dumps方法或dump方法。dumps方法可以將任意對象序列化成一個str,然后可以將這個str寫入文件進行保存。在Python Shell中示例如下:

>>> import cPickle as pickle
>>> d = dict(url='index.html',title='首頁',content='首頁')
>>> pickle.dumps(d)
"(dp1\nS'content'\np2\nS'\\xca\\xd7\\xd2\\xb3'\np3\nsS'url'\np4\nS'index.html'\n p5\nsS'title'\np6\ng3\ns."


如果使用dump方法,可以將序列化后的對象直接寫入文件中:

>>> f=open(r'D:\dump.txt','wb')
>>> pickle.dump(d,f)

>>> f.close()


pickle實現(xiàn)反序列化使用的是loads方法或load方法。把序列化后的文件從磁盤上讀取為一個str,然后使用loads方法將這個str反序列化為對象,或者直接使用load方法將文件直接反序列化為對象,如下所示:

>>> f=open(r'D:\dump.txt','rb')
>>> d=pickle.load(f)
>>> f.close()
>>> d {'content': '\xca\xd7\xd2\xb3', 'url': 'index.html', 'title': '\xca\xd7\xd2\xb3'}

通過反序列化,存儲為文件的dict對象,又重新恢復(fù)出來,但是這個變量和原變量沒有什么關(guān)系,只是內(nèi)容一樣。以上就是序列化操作的整個過程。

假如我們想在不同的編程語言之間傳遞對象,把對象序列化為標(biāo)準(zhǔn)格式是關(guān)鍵,例如XML,但是現(xiàn)在更加流行的是序列化為JSON格式,既可以被所有的編程語言讀取解析,也可以方便地存儲到磁盤或者通過網(wǎng)絡(luò)傳輸。

如對本文有疑問,請?zhí)峤坏浇涣髡搲?,廣大熱心網(wǎng)友會為你解答??! 點擊進入論壇

發(fā)表評論 (289人查看0條評論)
請自覺遵守互聯(lián)網(wǎng)相關(guān)的政策法規(guī),嚴(yán)禁發(fā)布色情、暴力、反動的言論。
昵稱:
最新評論
------分隔線----------------------------

其它欄目

· 建站教程
· 365學(xué)習(xí)

業(yè)務(wù)咨詢

· 技術(shù)支持
· 服務(wù)時間:9:00-18:00
365建站網(wǎng)二維碼

Powered by 365建站網(wǎng) RSS地圖 HTML地圖

copyright © 2013-2024 版權(quán)所有 鄂ICP備17013400號