天天看點

python 入門之 – 檔案操作(二十三)

學習

python

檔案操作之前,首先要知道我們一般在電腦圖形化界面上是如何操作的:

1、根據存放在電腦硬碟上的檔案路徑找到檔案

2、通過系統自帶的軟體或者第三方軟體打開選擇的檔案

3、進行閱讀浏覽或者增删改查等等…

4、操作完成後需要關閉檔案或者儲存關閉檔案(不然占用計算機運作記憶體)

其實在

python

裡面操作檔案還是挺容易的,還記的當初學

NodeJS

的時候還要引入一個對應的子產品才能進行操作,在

python

裡面可以直接用對應的操作檔案的内置函數就可以了。

open()

:

open

函數是

python

裡面用來操作檔案子產品的函數,好幾個參數和對應值,其實可以把他當作一個

json

對象,和

json

對象不同的是它不是

{}

來開始和結束的。

我現在在桌面建立一個檔案夾,就叫做:

demo

,裡面有兩個檔案,一個是我要編寫的

python

代碼,叫

app.py

,另一個是文本檔案取名為

name.txt

, 我現在來擷取用

open()

擷取

name.txt

的文本内容,文本内容如下

hello word
           

app.py

檔案内容如下:

# 擷取檔案函數 open() 
# 參數1 file="檔案路徑" 
# 參數2 mode="操作檔案的方式" r 代表文本隻讀模式
# 參數3 encoding="檔案路徑" 設定字元編碼,通常都用 utf-8
files = open(file="./name.txt",mode="r",encoding="utf-8")
           

在這裡我設定了一個變量

files

等于操作這個檔案的方法,那麼在這個檔案下面也有好幾個方法,先說說擷取檔案和關閉檔案。

.read()

: 擷取檔案内容

.close()

: 關閉檔案

# 擷取檔案
files = open(file="./name.txt",mode="r",encoding="utf-8")
# 将擷取到的内容指派給變量 data
data = files.read()
# 将擷取的内容列印出來
print(data)
# 檢視完成後直接關閉打開的程式
files.close()

>> hello word
           

上面方法是按照嚴格意義上來操作的,我個人對學習操作還是比較嚴謹的,如果你可以确定你打開的檔案本身就是

utf-8

的編碼檔案的話,其實你

encoding="utf-8"

可以不用寫,甚至

mode

權限也可以省略掉,如:

files = open(file="./name.txt")
data = files.read()
print(data)
files.close()

>> hello word
           

當然,還可以更加省略,連

file

都不用寫,直接寫上路徑,如:

files = open("./name.txt")
data = files.read()
print(data)
files.close()

>> hello word
           

當然如果在你不知道這個檔案是什麼編碼格式的時候你讀到的檔案隻會亂碼,是以需要換一種操作模式,你可以換成

二進制

的操作模式,也就是說,系統怎麼存儲,就以什麼格式讀取出來,當取到二進制資料的時候

python

會自動轉化成

十六進制

,拿到的資料就變成了

十六進制

的資料了,具體操作如下:

我将 name.txt 内的資料修改成中文編碼

gb2312

,并且将内容改成中文,如:

中國無敵
           

然後

python

代碼,将

mode

的屬性值從

r

後面加一個

b

b

本身代表了

二進制

,是以這裡是以

二進制

的形式讀取:

files = open(file="./name.txt", mode="rb")
data = files.read()
print(data)
files.close()

>> b'\xd6\xd0\xb9\xfa\xce\xde\xb5\xd0'
           

可以看到拿到的

python

已經拿到了

2進制

資料,因為

python

内置的是

16進制

,是以

二進制

的資料是以

16進制

的方式顯示出來了,這種操作模式一般是網絡傳輸的時候用的,例如前端擷取一個下載下傳位址,

python

作為後端将它輸出,因為當不知道檔案的字元編碼的時候

python

無法讀取到裡面真正的内容,隻能進行

二進制流

的資料傳輸,由其他用戶端或使用者電腦的編碼支援進行釋放内容。

如上方,如果在我不知道這個編碼格式的時候我又要取到這裡的檔案内容,那麼原生

python

是根本無法支援的,那麼這個時候又該怎麼辦呢,其實在

python

中确實不支援,可是

python

也有屬于他自己的生态庫。例如

NodeJs

NPM

生态庫,裡面有各種各樣給

NodeJS

提供的插件,也是我大前端發展至今必不可少功臣。那麼

python

的生态庫又是怎樣的呢?

NodeJS

一樣,在你安裝了

Node

運作環境後會自帶一個

NPM

,那麼在

python

裡面隻要你安裝了

python

,那麼必定會有一個

pip

的工具,我這邊蘋果電腦自帶一個

python2

版本的環境,是以他也必定有一個

pip

的工具,當我安裝完

python3

後,我電腦上又多了一個

pip3

pip3

pip

的更新版,如

py2

py3

一樣,我在我電腦上分别試一下自帶的

pip

py3

自帶的

pip3

,如:

首先來看看我自帶的

pip

python 入門之 – 檔案操作(二十三)

當你看到這個界面的時候就代表你電腦上确實安裝了

pip

,可以通過

pip

來安裝一些擴充應用程式

再來看看,我安裝

py3

的時候自帶的

pip3

python 入門之 – 檔案操作(二十三)

接下來就可以去

pip

官網查找一些關于

python

的一些第三方子產品包了,

pip

官網是:https://pypi.org/

我在官網找到了一個

python

的編碼判斷工具包,是根據轉化出來的

二進制

資料來判斷的,幾率不是百分之百準确,因為沒有百分之百準确的編碼判斷,但是他可以自動比對出幾率最高的一個編碼,這個工具包的名字叫做:

chardet

如下:

python 入門之 – 檔案操作(二十三)

我點選第一個進去 chardet 3.0.4 這是版本最高的一個,應該是目前編碼支援度最好的一個了,進去之後看到了如下界面:

python 入門之 – 檔案操作(二十三)

繼續往下翻動,可以看到操作流程,包括怎麼下載下傳的和怎麼使用的一些方法,如:

python 入門之 – 檔案操作(二十三)

要想使用必須先安裝,這裡列出了下載下傳方法,我根據這個方法進行安裝:

pip3 install chardet
           

我是在 python 的 ide 編輯器(pycharm)中安裝的,當看到以下界面就代表安裝成功了:

python 入門之 – 檔案操作(二十三)

在 pip 官網上并沒有改插件的操作方法,但是他把文檔位址給貼出來了,我們可以去他的文檔url位址裡面看看:

python 入門之 – 檔案操作(二十三)

當進入文檔後可以看到他有貼出 基本用法,我們去看看:

python 入門之 – 檔案操作(二十三)

進入基本用法的文檔後可以看到這個界面:

python 入門之 – 檔案操作(二十三)

這裡介紹了一個函數方法,叫做

detect()

我在程式裡面根據他的方法測試一下,如:

# 引入子產品包
import chardet

# 檔案内容
files = open(file="./name.txt", mode="rb").read()

# chardet 工具包内置的測試 detect函數 轉碼,列印出來是字典資料類型
data = chardet.detect(files)

print(data)

>> {'encoding': 'IBM855', 'confidence': 0.5119798157077455, 'language': 'Russian'}

#驚呆了,我明明設定的是 GB2312 怎麼變成了 IBM855

# 通過字典 get 方法取到 encoding 編碼格式
code = data.get('encoding')

# 再通過内置函數進行解碼
text = files.decode(code)

print(text)

>> ол╣Щ╬яхл
           

嗯?驚呆了,我不知道為什麼會失敗,我努力分析了很久。這個包是根據二進制位元組判斷的,難道是位元組不夠長,産生的誤差嗎?我重新在 name.txt 加入一段 ‘中國無敵’ 現在一共又八個字 中國無敵中國無敵,我重新測試一遍。

# 引入子產品包
import chardet

# 檔案内容
files = open(file="./name.txt", mode="rb").read()

# chardet 工具包内置的測試 detect函數 轉碼,列印出來是字典資料類型
data = chardet.detect(files)

print(data)

>> {'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}

# 通過字典 get 方法取到 encoding 編碼格式
code = data.get('encoding')

# 再通過内置函數進行解碼
text = files.decode(code)

print(text)

>> 中國無敵中國無敵
           

果然還是位元組太少産生的判斷失誤,看來也要又一定的量級才能夠将判斷正确的比例拉大,但是這已經很不錯了。雖然有點坑,但是作為一個标準的程式員,本身就要有面對挫折勇于接受并且克服困難的決心,并且要謹記盡量少在一個坑裡多掉幾次。

其實上面介紹了怎麼讀檔案,可是真正當讀取一個檔案的時候,當一個檔案内容太龐大,如果有好幾個

G

的容量,一次性讀取出來,那麼就需要很久很久了,最簡單的例子就是多媒體檔案,像什麼視訊、音樂等檔案,那麼在這種情況下,該怎麼保證性能和速度的前提下去操作呢?

其實可以用循環來讀取,可是循環的話,還是需要判斷字元編碼,在判斷字元編碼之後才能進行循環,否則判斷字元編碼,需要一段時間,然後讀取又需要一段時間,在加上 python本省是一門進階程式設計語言,運作速度有限,不像底層的

c

c++

...

是以可以這麼操作,讀檔案的時候首先,你伺服器上得有檔案,是以一開始必須是使用者上傳檔案,在使用者上傳檔案的時候你不管三七二十一先直接接收了,然後給用戶端傳回一個

code

等于

200

,不占用使用者的時間,然後上傳完檔案在使用者不知道的情況下,背景重新讀取檔案,判斷字元編碼,然後以

utf-8

的編碼格式存儲起來,然後在使用者需要讀取的時候,就什麼也不用管了直接以

utf-8

的編碼格式循環讀取,直接傳回給用戶端,這樣一來就不會占用使用者的時間,而且這種方式更加友好,但是怎麼循環呢?如下操作:

我先在網上随便下載下傳一個小說檔案,并且轉成

utf-8

的編碼格式,然後我就直接以

utf-8

的編碼方式使用循環讀取,小說名為:all.txt ,我在 pycharm 裡面打開,拖到最下面可以看到有七萬多行,一共有6.02mb:

python 入門之 – 檔案操作(二十三)

現在我直接用以下循環代碼去讀它:

# 擷取檔案
files = open(file="./all.txt",mode="r",encoding="utf-8")
# 循環整個檔案
for i in files:
    # 依次列印
    print(i)
#讀取完檔案關閉檔案
files.close()
           

執行結果如下:

python 入門之 – 檔案操作(二十三)

它被依次列印出來了,并且小說裡面的換行它裡面也會換行,其實使用者每一個檔案裡面的換行,可能使用者自己不知道,也看不到,他是有一個換行符的

\n

那麼

python

是根據換行符來讀取的,一段一段的往外輸出,是以就是我現在

python

控制台當中的這個樣子。

寫檔案

現在開始說一說寫檔案,如上方所說,在使用者上傳完檔案後,我不可能直接将使用者的檔案轉成

utf-8

的編碼,我需要在使用者上傳完畢後,通過第三方擴充包,去讀檔案,判斷檔案什麼類型,然後再以檔案類型去讀取,最後在建立一個檔案,以

utf-8

的編碼格式轉換,依次循環寫入,當寫入完成後,删除使用者的原有檔案,并且依次命名,但是首先先來看看什麼是寫檔案。

#在這裡 mode 的值寫成 w 代表的就是寫入檔案,和 r 一樣 也可以以二進制寫入 wb
files = open(file="./寫入的檔案.txt",mode="w")
#write() 方法是 open 下的寫入檔案的方法,預設編碼格式為 utf-8 
#也可以追加一個參數為 encode('utf-8') 如:
#files.write('hello word',encode('utf-8'))
files.write('hello word')
files.close()
           

在執行上面代碼前我的 demo 檔案夾裡面隻有

app.py

name.txt

all.txt

這三個檔案,并沒有

寫入的檔案.txt

,因為在寫入檔案的時候

python

會自動判斷你的檔案裡面是否有這個檔案,如果該名稱檔案不存在,會自動建立該名稱檔案,并且寫入對應的資料,當然,如果你已經存在了一個檔案并且這個檔案裡面已經有了一些内容,那麼你寫入的内容不會追加在你的内容後面,而是相當于你的内容全部清空然後把重新寫的内容給覆寫進去,那麼如何在已有的檔案裡面追加内容呢?如下:

#在這裡 mode 的值寫成 a 代表的就是追加模式,和 r 一樣 也可以以二進制寫入 wb
files = open(file="./寫入的檔案.txt",mode="a")
#write() 方法是 open 下的寫入檔案的方法,預設編碼格式為 utf-8 
#也可以追加一個參數為 encode('utf-8') 如:
#files.write('hello word',encode('utf-8'))
files.write('hello word')
files.close()
           

可以看到上方

追加模式

的代碼個

寫入模式

的代碼基本一摸一樣,唯一不一樣的就是

mode

value

值,當

value = r

代表讀檔案,當

value = w

等于寫模式,當

value = a

代表追加模式,再次運作程式後打開

寫入的檔案.txt

發現 内容變成了

hello wordhello word

上面說了三種操作檔案的方法,檔案讀取,檔案寫入和檔案追加,但是都不能向電腦圖形化界面系統一樣邊讀邊寫,那麼如果我現在有一百行代碼,我需要一直讀取讀到第五十行代碼的時候把它改掉,然後繼續往下讀,這樣我應該怎麼操作呢?

如我現在把

寫入的檔案.txt

全部手動清空,然後通過循環寫入一百行代碼如:

files = open(file="./寫入的檔案.txt",mode="a")
num = 0
while num<100:
    num += 1
    files.write('第'+str(num)+'行:hello word\n')
files.close()
           

當執行完後,在我的

pycharm

裡面看看是否寫入成功了:

python 入門之 – 檔案操作(二十三)

可以看到寫入成功了,但是有一個小問題,那就是出現了 101 行,可能是因為我在寫入的時候加了一個換行符

\n

的原因,那麼我現在再次清空,在循環裡面加入一個判斷:

files = open(file="./寫入的檔案.txt",mode="a")

num = 0
while num<100:
    num += 1
    files.write('第' + str(num) + '行:hello word') if num == 100 else files.write('第'+str(num)+'行:hello word\n')

files.close()
           

再次打開

寫入的檔案.txt

文檢視:

python 入門之 – 檔案操作(二十三)

這次就剛好了,一百行,一行不多一行不少,那麼現在我想更改第五十行的代碼該怎麼辦呢?如果按照上面介紹的三種方式肯定是不行的,是以接下來要介紹一種

混合模式

,什麼是

混合模式

呢?

混合模式就就是既可以讀資料,也可以寫資料,當然和上面三種方式一樣,都是在改變 mode 的 value 值 :

r+

: 讀寫模式

w+

: 寫讀模式

如上方,讀寫模式和寫讀模式差別在于哪裡呢,先來看看讀寫模式:

files = open(file="./寫入的檔案.txt",mode="r+")

#已經存在的檔案
data = files.read()

print(data)

# 測試分隔符
print('--------------------')

# 新加入的内容
files.write('\n123123')

# 新加完資料之後重新讀取
print(files.read())

# 關閉檔案
files.close()
           

我先不去看他的運作結果,按照正常的邏輯來說,運作最後的結果應該是列印了三次,第一次把原有的資料列印出來,第二次列印分隔符,第三次把已有的内容和新增的内容全部加在一起列印出來,可是當我真正運作後看到我的運作結果後,我就蒙蔽了,如:

python 入門之 – 檔案操作(二十三)

what? 怎麼會這樣,在分隔符後面啥也沒有,不是按照正常的後面應該還有一段

123123

嗎?我打開

寫入的檔案.txt

看了看,發現其實内容是寫進去了的,确實,我是先讀取了資料,然後在寫入了,都成功了,但是為什麼寫入之後就讀取不到了呢?

其實答案很簡單,就和我們在電腦上寫文字一樣,他是有一個光标的,讀取檔案的時候光标一直往下走,就一次性走到了最後,然後你每次寫入一個字元集進入檔案,就像你每次打了一個字,光标始終會在最後一個,是以光标後面始終是沒有資料的,但是當你第二次執行讀檔案的時候就會發現,之前添加的檔案,其實是可以列印出來的。

上面這種方式就叫做讀寫模式,那麼看看混合模式的第二種,寫讀模式:

files = open(file="./寫入的檔案.txt",mode="w+")

#已經存在的檔案
data = files.read()

print(data)

# 測試分隔符
print('--------------------')

# 新加入的内容
files.write('\n123123')

# 新加完資料之後重新讀取
print(files.read())

# 關閉檔案
files.close()
           

和讀寫模式一樣,我隻是把

r+

換成了

w+

,我現在運作程式,這個時候發現除去測試分隔符之外什麼都沒列印出來,我去到檔案裡面看看,發現整個内容隻有兩行,第一行什麼也沒有,第二行是

123123

,可能從字面上的意思上來說

讀寫模式

寫讀模式

并沒有什麼很大的差異,但是

寫讀模式

基本上用的很少,可以說用不到,因為

寫讀模式

是用 寫檔案的方式 優先清空檔案内所有資訊,然後再讀取,但是檔案輸入的

光标

在寫完了之後還是走到了最後 ,是以它讀到的資料是空的。這就是

混合模式

,我們如果做内容修改的話,檔案的

混合模式

是必學的一個知識點,然後就是如何控制輸入的

光标

,這樣我們就可以随意的讀取檔案任意部分的内容了。

其實檔案操作還有很多方法,包括如何操作

光标

之類的,先别急,我一個一個來示範:

flush()

: 重新整理檔案内部緩沖區,直接把内部緩沖區的資料寫入檔案,而不是被動的等待輸出緩沖區寫入

readable()

: 判斷檔案是否可讀

readline()

: 讀取整行,包括 ‘\n’ 換行字元在内

next()

: 傳回檔案下一行

tell()

: 傳回檔案内光标的所在位置

seek()

: 設定檔案内光标的目前位置

seekaable()

: 判斷檔案是否可以進行

seek()

方法操作

writeable()

: 判斷檔案是否可以寫入

readlines()

: 讀取所有行,并傳回清單

read()

: 讀取檔案内容

fileno()

: 方法傳回一個整型的檔案描述符(file descriptor FD 整型),可用于底層作業系統的 I/O 操作

isatty()

: 如果一個檔案連接配接到終端裝置傳回 True,否則傳回 False

writelines()

: 像檔案寫入一個序列的字元串清單,如果需要換行,則手動加入換行符

truncate()

: 截取檔案,截取的位元組通過參數指定,預設為目前檔案位置

flush()

學習關于 flush 方法先來看一個小執行個體,首先我清空

寫入的檔案.txt

,然後我在終端操作,如:

python 入門之 – 檔案操作(二十三)

可以看到,我寫入了十個位元組 ,然後我在 pycharm 裡面打開該檔案:

python 入門之 – 檔案操作(二十三)

發現這個檔案裡面什麼都沒有,并沒有寫入任何東西,然後我在終端關閉這個檔案:

python 入門之 – 檔案操作(二十三)

再次打開 pycharm 檢視

寫入的檔案.txt

python 入門之 – 檔案操作(二十三)

發現其實他已經寫入進來了,這個應該不難了解,就好比我們編寫一個檔案,當我們打開檔案後,開始編寫,當我們編寫完成後,肯定要

command + s

儲存,然後關閉,再次打開的時候他其實就已經存在了,如果在你編寫該檔案的時候沒有儲存再次在另一個軟體裡面打開,其實看到的就是空的,那麼他編寫的内容其實并沒有真正存儲到硬碟當中,而是在計算機的運作記憶體當中,隻有當你儲存了之後才會真正寫入到硬碟當中去,至于為什麼不寫一個就直接儲存一個到硬碟當中去那是因為,從運作記憶體到硬碟記憶體的寫入速度是相當慢的,是以

python

預設不支援這樣的操作,但是他支援一個實時更改的内置方法,在業務場景需要的情況下允許這樣做,是以

flush()

函數誕生了,如:

files = open(file="./寫入的檔案.txt",mode="a")

files.write('\nhello')

files.flush()
           

接下來再看看

寫入的檔案.txt

python 入門之 – 檔案操作(二十三)

readable()

判斷檔案是否可讀,這個不是很難,據兩個例子就明白了:

files = open(file="./寫入的檔案.txt",mode="r")
print(files.readable())

>> True

files = open(file="./寫入的檔案.txt",mode="w")
print(files.readable())

>> False
           

readline()

隻讀一行,這個很簡單,也就是說遇到了換行符就停止了不再往下讀取了,如:

#寫入的檔案.txt
hello word1
hello word2
hello word3
hello word4

#app.py
files = open(file="./寫入的檔案.txt",mode="r")
print(files.readline())
print(files.readline())

>> hello word1
>
>  hello word2
           

next()

傳回檔案的下一行,這個其實也不是很難,如:

files = open(file="./寫入的檔案.txt",mode="r")

#循環三次
for index in range(3):
    line = next(files) #next的參數為檔案,這樣才能讀取
    print(line) #依次列印變量

# 關閉檔案
files.close()

>> hello word1
>> hello word2
>> hello word3
           

tell()

傳回目前檔案操作的光标所在位置,他傳回的是一個位元組的數字,如:

files = open(file="./寫入的檔案.txt",mode="r")
#每次往下讀取一行資料,然後列印依次目前光标行走的位置
files.readline()
print(files.tell())

files.readline()
print(files.tell())

files.readline()
print(files.tell())

files.readline()
print(files.tell())

# 關閉檔案
files.close()

>> 12
   24
   36
   47
           

seek()

設定檔案内光标的目前位置,如:每次設定完光标的所在位置之後隻讀取一行

files = open(file="./寫入的檔案.txt",mode="r")

#每次隻讀一行
print(files.readline())
# 将光标設定到第一個
files.seek(0)
#每次隻讀一行
print(files.readline())

# 關閉檔案
files.close()

>> hello word1

   hello word1
           

seekaable()

判斷檔案是否可以進行

seek()

方法操作,其實這個沒什麼好示範的,反正就是如果能夠進行

seek()

方法操作就會傳回

True

,否則傳回的就是

False

,可能會有朋友問,還有不能操作的檔案?當然有,在

Linux

上一切皆檔案,一個驅動都是檔案,一個運作程式也是檔案,當然這一類的檔案傳回的肯定是

False

writeable()

判斷檔案是否可以寫入,其實這個也沒什麼好示範的,其實隻要把

mode

改成

r

就不可以寫入了,其實的和上面這個

seekaable()

方法一樣的

readlines()

讀取所有行,并傳回清單,以每一行的換行符為一個結尾計算,如:

files = open(file="./寫入的檔案.txt",mode="r")

print(files.readlines())

# 關閉檔案
files.close()

>> ['hello word1\n', 'hello word2\n', 'hello word3\n', 'hello word4']
           

read()

其實這個方法,在一開始的時候已經示範過了很多次,但都是直接使用的,并沒有在裡面傳參數,現在我在裡面傳遞一個參數看看

files = open(file="./寫入的檔案.txt",mode="r")

print(files.read(1))

# 關閉檔案
files.close()

>>  h
           

fileno()

方法傳回一個整型的檔案描述符(file descriptor FD 整型),可用于底層作業系統的 I/O 操作

files = open(file="./寫入的檔案.txt",mode="r")

print(files.fileno())

# 關閉檔案
files.close()

>> 3
           

isatty()

如果連接配接到一個終端裝置傳回 True,否則傳回 False,我這裡并沒有連接配接到終端裝置,是以一定傳回的是 False

files = open(file="./寫入的檔案.txt",mode="r")

print(files.isatty())

# 關閉檔案
files.close()

>> False
           

writelines()

像檔案寫入一個序列的字元串清單,如果需要換行,則手動加入換行符:

#以檔案的寫方式操作
files = open(file="./寫入的檔案.txt",mode="w")

data = [
    'hello\n',
    'word'
]

files.writelines(data)

# 關閉檔案
files.close()
           

當我再次打開這個檔案後發現隻有以下内容:

python 入門之 – 檔案操作(二十三)

truncate()

截取檔案,截取的位元組通過參數指定,預設為目前檔案位置,如:

files = open(file="./寫入的檔案.txt",mode="r+")

files.truncate(4)

files.close()
           

當運作完成後我打開

寫入的檔案.txt

,裡面的内容變成了這樣子:

python 入門之 – 檔案操作(二十三)

發現隻留下來了四個字元,也就是說不管檔案内有多少個字元,我可以根據指定的參數,隻截取一部分内容長度的位元組出來。

這裡的檔案操作有一個關于字元編碼的問題,在中國我們一般用的字元編碼,都是

utf-8

gbk

的編碼,在

gbk

裡面一個字占據

2

個位元組,在

utf-8

裡面一個字占據三個位元組,是以進行一些操作的時候千萬要記住,不要因為字元編碼的問題搞出亂碼的問題,這裡我來做一個示範:

我把

寫入的檔案.txt

内容改成:中國萬歲,如:

python 入門之 – 檔案操作(二十三)

這裡的

寫入的檔案.txt

我用的是

utf-8

的字元集,現在我來用

truncate()

方法截取字元:

files = open(file="./寫入的檔案.txt",mode="r+")

files.truncate(9)

files.close()
           

當我運作完成之後,打開

寫入的檔案.txt

,内容是這樣的:

python 入門之 – 檔案操作(二十三)

我現在把 9 個位元組改成 8 以下,如:

files = open(file="./寫入的檔案.txt",mode="r+")

files.truncate(8)

files.close()
           

再次打開

寫入的檔案.txt

内容是這樣的:

python 入門之 – 檔案操作(二十三)

可以看到已經亂碼了,是以一定要切記,

utf-8

的字元集一個中文占據 3 個位元組,

gbk

一個中文占據 2 個位元組,是以千萬不能犯這種低級的錯誤。

在以上介紹的方法中,操作檔案的方法,

read()

方法是按一個字元來操作,

truncate()

tell()

seek()

這幾種都是用來操作位元組的。

言歸正傳,回到之前那個問題,我現在介紹了這麼多方法,其實能用得到的方法基本上全部介紹了個遍,是以現在我來進行檔案修改,可能有朋友會問了,上面的方法都不能進行檔案修改,你還沒介紹檔案修改的方法呢,其實說句真心話,python 還真沒有這個方法,我能想到的思路就是,通過循環,依次讀取檔案的每一行,然後建立新的檔案加進去,把要修改的通過字元串的 replace() 方法替換了,如:

寫入的檔案.txt

内容如下:

每天學習一點
讓自己更加強大一些
即便滿身疲憊
也裝出一副輕松的模樣
           

我現在把第二行的

自己

改成一個

# 修改的檔案名稱
name1 = '寫入的檔案'
# 用字元串的方法copy一個新的檔案加上編号命名
name2 = '%s(1).txt'%name1

# 需要修改的内容
original = '自己'
# 修改成什麼内容
change = '我'

# 需要修改的檔案
files = open(file=name1+'.txt',mode='r',encoding='utf-8')
# 新增并寫入的檔案
files2 = open(file=name2,mode='w',encoding='utf-8')

# 循環需要修改的檔案,将每一行的内容以字元串的形式指派給變量 i
for i in files:
    # 逐行判斷是否有需要修改的内容
	if original in i:
        # 判斷成立用字元串方法替換内容并且指派給目前循環次數的變量i
		i = i.replace(original,change)
    # 每一行結束後 i 都代替了目前這一行的資料,然後将這一行給添加進新的檔案
	files2.write(i)


# 執行結束後關閉兩個檔案
files.close()
files2.close()
           

當程式運作結束後,我可以看到我目前目錄下多了一個叫做

寫入的檔案(1).txt

的檔案,我将該檔案的内容打開,然後看到的結果如下:

python 入門之 – 檔案操作(二十三)

可以看到執行成功了

自己

變成了

,然而這并沒有完成,因為我要做的是修改檔案,但是這并不屬于修改檔案,而是新增了一個檔案,是以這個時候我的思路一變,有兩個方案出現了:

1、清空原有檔案的内容,然後将新增的檔案内容讀取過來指派給原有的檔案,最後删除新增的檔案

2、将新增的檔案重命名覆寫原有的檔案

這樣一來不管這兩個怎麼着,都實作了修改檔案的這個功能,可是上面又沒有介紹删除檔案的方法,也沒有介紹檔案重命名的方法,于是我就找資料看書和前輩們的整理出來的資料,畢竟現在學技術已經是站在了巨人的肩膀上了,我們的前輩已經給出了太多的方案,具體如下:

在 python 裡面有一個内置的子產品,叫做 os ,和之前的深度copy是一樣的,都需要引入改子產品,在 os 子產品裡面我找到了兩個方法:

rename()

: 檔案重命名

remove()

: 删除檔案

因為删除方法太麻煩來,要寫兩邊,不過稍後我會示範如何删除檔案,但是就不在這個例子上示範了,我先用重命名的方法來實作功能這個功能例子:

import os

# 修改的檔案名稱
name1 = '寫入的檔案'
# 用字元串的方法copy一個新的檔案加上編号命名
name2 = '%s(1).txt'%name1

# 需要修改的内容
original = '自己'
# 修改成什麼内容
change = '我'

# 需要修改的檔案
files = open(file=name1+'.txt',mode='r',encoding='utf-8')
# 新增并寫入的檔案
files2 = open(file=name2,mode='w',encoding='utf-8')

# 循環需要修改的檔案,将每一行的内容以字元串的形式指派給變量 i
for i in files:
    # 逐行判斷是否有需要修改的内容
	if original in i:
        # 判斷成立用字元串方法替換内容并且指派給目前循環次數的變量i
		i = i.replace(original,change)
    # 每一行結束後 i 都代替了目前這一行的資料,然後将這一行給添加進新的檔案
	files2.write(i)


# 執行結束後關閉兩個檔案
files.close()
files2.close()

os.rename(name2,name1+'.txt')
           

當程式執行完成之後之前的會發現,之前的檔案已經因為新加的檔案重命名給替換了,然後新的檔案取而代之了原有的檔案:

python 入門之 – 檔案操作(二十三)

好了,檔案重命名方法已經完成了,現在來看看删除方法的使用我現在删除這個檔案如:

import os

os.remove('寫入的檔案.txt')
           

當我運作完成之後在我的 pycharm 裡面已經看不到這個檔案了:

python 入門之 – 檔案操作(二十三)

關于檔案的操作就基本上全部學完了,當然了,如果你覺得真的就這麼多的話,你應該去翻閱翻閱相關的書籍了,我隻是把常用的方法列出來了而已,每一門程式語言都夠學的了,不過當你學完上面這些操作方法,再看看那些偏門的方法其實會覺得已經很容易了。

繼續閱讀