摘要:如果該文件已存在,文件的初始指針在文件的結尾。文件中只有一句話十步殺一人,千里不留行。關閉文件如果用來打開文件的話就不用管關閉文件的操作了,因為已經幫你完成了這一步,否則必須在處理文件之后加上關閉文件的操作
讀取文件的操作步驟
有一道腦筋急轉彎,問把大象裝進冰箱的步驟,答案很簡單,打開冰箱、把大象推進去、關閉冰箱。這就是一個處理問題的思路,我們對文件的操作和這個一樣,第一步:打開文件;第二部:處理文件(讀取或者寫入);第三部關閉文件,怎么樣?其實很簡單吧,下面我們就來詳細說說文件的操作。
打開文件open(file, mode="r", buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
打開文件要使用open()函數,()內涉及的參數在初期階段我們只需要知道三個參數即可,那就是file、mode、和encoding
file首先是文件名,類型是字符串,要包含路徑,如果要打開的文件和當前文件在同一個目錄下則可以省略路徑(相對路徑).
mode然后是打開文件的模式,格式是:mode="模式", 這里的"mode="可以省略,直接寫模式即可,如果不指定模式則默認為r,具體的模式如下:
這里引入一個偽名詞——指針,想象一下當你在word中編輯文本時有個光標吧?你可以把指針想象成那個光標,光標在哪里你對文件的所有操作就從哪里開始。
r 只讀。文件的初始指針在文件的開頭。這是默認模式。 rb 只讀的二進制格式。文件的初始指針在文件的開頭。 r+ 讀寫。文件的初始指針在文件的開頭。 rb+ 讀寫的二進制格式。文件的初始指針在文件的開頭。 w 只寫。如果該文件已存在則打開文件,清空文件內容。如果該文件不存在,則創建新文件。 wb 只寫的二進制格式。如果該文件已存在則打開文件,清空文件內容。如果該文件不存在,創建新文件。 w+ 寫讀。如果該文件已存在則打開文件,清空文件內容。如果該文件不存在,創建新文件。 wb+ 寫讀的二進制格式。如果該文件已存在則打開文件,清空文件內容。如果該文件不存在,創建新文件。 a 追加寫。如果該文件存在,文件的初始指針在文件的結尾。新的內容將會被寫入到已有內容之后。如果該文件不存在,創建新文件進行寫入。 ab 追加寫的二進制格式。如果該文件存在,文件的初始指針在文件的結尾。新的內容將會被寫入到已有內容之后。如果該文件不存在,創建新文件進行寫入。 a+ 追加寫讀。如果該文件已存在,文件的初始指針在文件的結尾。文件打開時會是追加模式。如果該文件不存在,創建新文件用于讀寫。 ab+ 追加寫讀的二進制格式。如果該文件已存在,文件的初始指針在文件的結尾。如果該文件不存在,創建新文件用于讀寫。encoding
第三個參數是文件的編碼(非二進制格式時使用),編碼的設置必須與要打開的文件的編碼一致,否則會報錯,也就是說源文件是用什么編碼寫入的,你打開時就得用什么編碼打開。
處理文件我們來舉一個出錯的例子,要實現的操作是打開文件名為“test”的文件,原文件編碼為utf-8,而我們打開時使用了gbk編碼。
文件中只有一句話:十步殺一人,千里不留行。
代碼如下:
file = open("test","r",encoding="gbk") content = file.read() print(content) file.close()
這里說明以下,open函數返回的結果是一個文件對象,所以要用一個變量接收一下(file),
這樣我們就可以方便地使用這個對象的方法了,比如file.read(),file.write,file.flush()等等
read()是文件對象的一個方法,作用是讀取指定的字符數,如果未指定則默認讀取所有內容
但是上面的代碼執行后會報錯,下面是報錯信息,大意是gbk編碼無法解碼(文件打開的過程實際就是解碼的過程)
--------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last)in () 4 #這里說明以下,open函數返回的結果是一個文件對象,所以要用一個變量接收一下(file),這樣我們就可以方便地使用這個 5 #對象的方法了,比如file.read(),file.write,file.flush()等等 ----> 6 content = file.read()#read()是文件對象的一個方法,作用是讀取指定的字符數,如果未指定則默認讀取所有內容 7 print(content) 8 file.close() UnicodeDecodeError: "gbk" codec can"t decode byte 0xad in position 4: illegal multibyte sequence
解決的辦法很簡單,把編碼方式改為utf-8即可,因為linux系統默認是utf-8編碼,所以編碼也可以省略不寫,又因為我們只是要讀取下文件,所以模式為r,而默認模式為r,也可以省略不寫。
所以代碼就變成了下面的樣子:
file = open("test") content = file.read() print(content) file.close() 輸出為: 十步殺一人,千里不留行
方法read()中也可以添加數字參數,作用是指定讀取的字符數,不管是漢字還是字母一個字符對應一個字母或者漢字,這里一定要和字節區分開,例子如下:
file = open("test") content = file.read(3) print(content) file.close() 輸出為: 十步殺
我們之前使用的打開文件的方式比較麻煩,因為必須要在結束時寫關閉文件的語句,這里介紹一種簡便的方法,格式是:
with open() as file_name: 操作代碼......
使用這種方法的好處是不用寫關閉文件的語句,with 和as是關鍵字,記住格式即可.
接下來我們創建一個二進制格式的文件
with open("二進制","wb") as file: file.write("十步殺一人,千里不留行".encode("utf8"))
因為我們打開文件的方式是以二進制格式打開的,那么在寫入文件時就要寫入二進制格式的字符串,但是對于”十步殺一人,千里不留行“這個字符串的二進制格式是什么呢?我們并不知道,所以我們使用.encode(utf8)來把這個字符串轉換成二進制格式。實際上我們通過另外一段代碼是可以知道這個字符串對應的二進制格式的,代碼如下:
print("十步殺一人,千里不留行".encode("utf8")) 輸出的二進制格式(表現形式為16進制,為什么?因為二進制太長了啊!!!)為: b"xe5x8dx81xe6xadxa5xe6x9dx80xe4xb8x80xe4xbaxbaxefxbcx8cxe5x8dx83xe9x87x8cxe4xb8x8dxe7x95x99xe8xa1x8c"
在實際中我們當然不可能寫這么長的東西,所以我們使用.encode("utf8")來轉化。轉化時我們使用了utf-8的編碼方式。
在這里說明一下為什么要編碼,想弄清楚這件事就要明白計算機的存儲原理。
簡單地講,文件在計算機中都是以二進制格式存儲的,對于計算機來講只有兩個數字有意義,那就是0和1,也就是二進制,而不同的0和1的組合代表不同的含義(編碼不同),比如在gbk編碼下一個漢字由兩個字節表示,也就是16位二進制數(16個0和1的組合),而在utf-8編碼下一個漢字由3個字節表示,也就是24位二進制數(24個0和1的組合),而我們現在要給計算機存儲的就是0和1的組合,那么在讀取文件或者轉化字符串時,如果你不告訴計算機你使用的是哪種編碼的話,計算機怎么可能知道這些0和1的組合代表什么含義呢?所以從計算機取出數據或者把普通字符串轉化成二進制格式時你必須告訴計算機你使用的是什么編碼方式。
在本例中使用utf-8編碼,所以在字符串后面加上.encode(utf8)
那么為什么平時可以直接寫入普通字符串呢?那是因為在用open()函數打開文件的時候就已經指定了編碼方式。
形象地解釋:open函數相當于打開了一種通道,平時打開時都是用某種編碼的方式打開的,所以我們在寫入內容時不必管它以什么編碼進入通道的(因為在open函數里面就已經指定了編碼方式)
而當open函數使用二進制格式打開時(就是帶b的模式),這個通道就沒有指定編碼方式,通道里面只有二進制,所以此時往通道里面放入非二進制格式內容的話就需要指定一種編碼方式。除非你直接在file.write()函數中直接寫二進制,但是人類是不可能記住那么多二進制組合所代表的含義的。
然后我們來讀取一下上面創建的名字為“二進制”的這個文件
with open("二進制","rb") as file: print("不指定解碼方式時的結果:",file.read())
如果我們在讀取時不指定解碼方式,那么輸出的結果就是下面這種人類無法理解的奇怪的東西(實際上它是用16進制表示的二進制)
不指定解碼方式時的結果: b"xe5x8dx81xe6xadxa5xe6x9dx80xe4xb8x80xe4xbaxbaxefxbcx8cxe5x8dx83xe9x87x8cxe4xb8x8dxe7x95x99xe8xa1x8c"
所以我們在讀取時也要指定編碼:
with open("二進制","rb") as file: content = file.read() print("指定解碼方式后的結果:",content.decode("utf-8")) 指定解碼方式后的結果: 十步殺一人,千里不留行
其他的在讀取時可能用到的方法:
readline()讀取一行,如果里面添加了參數n,則會讀取n個字符(我覺得這是個bug,貌似沒什么卵用) readlines()讀取所有內容,結果返回一個列表,元素由每一行組成。 tell()會輸出當前指針的位置,注意,該位置是以字節來計算的,不是字符 seek()重新指定指針位置。
使用readlines()并不是一個好方法,因為是一次性將文件都讀取到內存中,如果文件較大時則造成內存溢出,實際中使用下面的方法,系統會自動生成一個迭代器,用迭代的方法把需要的數據取出來。
with open("libai") as f: for i in f: #這里的i實際就是迭代后的每一行,用for循環的方式從文件對象中取出來,取一行讀一行,節省內存 print(i)
趙客縵胡纓,吳鉤霜雪明。銀鞍照白馬,颯沓如流星。 十步殺一人,千里不留行。事了拂衣去,深藏身與名。 閑過信陵飲,脫劍膝前橫。將炙啖朱亥,持觴勸侯嬴。 三杯吐然諾,五岳倒為輕。眼花耳熱后,意氣素霓生。 救趙揮金錘,邯鄲先震驚。千秋二壯士,烜赫大梁城。 縱死俠骨香,不慚世上英。誰能書閣下,白首太玄經。關閉文件
如果用with open() 來打開文件的話就不用管關閉文件的操作了,因為Python已經幫你完成了這一步,否則必須在處理文件之后加上關閉文件的操作:file_name.close()
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/42554.html
摘要:今天我們來討論下下如何實現打開文件修改文件關閉文件的操作本文采用逐行解釋的方法。這樣,我們就實現了文件的修改。 今天我們來討論下python下如何實現:打開文件—修改文件——關閉文件的操作 本文采用逐行解釋的方法。 思路: 第一步:把文件讀取出來第二部:再用w模式寫入到新文件第三部:把原文件刪除,并且把新文件重命名回原文件這樣就實現了文件的修改操作 我們先來看看原文件的內容 with ...
摘要:它則是以行為單位返回字符串,也就是每次讀一行,依次循環,如果不限定,直到最后一個返回的是空字符串,意味著到文件末尾了。 讀文件 在某個文件夾下面建立了一個文件,名曰:130.txt,并且在里面輸入了如下內容: learn python http://qiwsir.github.io qiwsir@gmail.com f = open(123.txt) #打開已經存在的文件,此文件在當前...
摘要:可以對文件進行查看創建等功能,可以對文件內容進行添加修改刪除,且所使用到的函數在為,在同時支持和,但是在系列移除了函數。在及以后,又支持同時對多個文件的上下文進行管理,即原文鏈接 Python可以對文件進行查看、創建等功能,可以對文件內容進行添加、修改、刪除,且所使用到的函數在Python3.5.x為open,在Python2.7.x同時支持file和open,但是在3.5.x系列移除...
摘要:其實,迭代器遠遠不止上述這么簡單,下面我們隨便列舉一些,在中還可以這樣得到迭代對象中的元素。 跟一些比較牛X的程序員交流,經常聽到他們嘴里冒出一個不標準的英文單詞,而loop、iterate、traversal和recursion如果不在其內,總覺得他還不夠牛X。當讓,真正牛X的絕對不會這么說的,他們只是說循環、迭代、遍歷、遞歸,然后再問這個你懂嗎?。哦,這就是真正牛X的程序員。不過,...
摘要:解析配置模塊之詳解基本的讀取配置文件直接讀取文件內容得到所有的,并以列表的形式返回得到該的所有得到該的所有鍵值對得到中的值,返回為類型得到中的值,返回為類型,還有相應的和函數。是最基礎的文件讀取類,支持對變量的解析。 Python 解析配置模塊之ConfigParser詳解 1.基本的讀取配置文件 -read(filename) 直接讀取ini文件內容 -sections() 得到所有...
閱讀 1250·2023-04-26 01:38
閱讀 1462·2021-11-15 11:39
閱讀 3251·2021-09-22 15:43
閱讀 2638·2019-08-30 15:55
閱讀 2047·2019-08-30 14:17
閱讀 2851·2019-08-29 14:16
閱讀 3062·2019-08-26 18:36
閱讀 2607·2019-08-26 12:19