嗚嗚嗚,好久沒更新了,
今天我們來聊聊IO流,之前我們用java中的IO流對檔案進行了一些簡單的操作,這次我們用Python作為基礎語言來學習如何使用檔案中的IO流,
有這樣一道作業:

圓周率的前100萬位小伙伴們可以自行到網上下載,或者聯系我:3611544427@qq.com,
這是一個簡單的檔案讀取和寫入的作業,對于Python中檔案物件的使用細則,限于篇幅,就不細講了,在這,我只介紹幾個常用的檔案函式:
1. tell()
獲取檔案指標的位置,之后的寫入等操作都是從檔案指標處開始操作,
2. read()
用于讀取整個檔案,回傳一個字串,可以添加一個引數,如 read(100) 表示讀取從檔案指標處開始的100個位元組,唯一需要注意的是,執行read(100)后,檔案指標會向后移動100位,
3. seek(offset , whence = 0)
seek() 函式用于控制檔案指標偏移的量,
- offset :開始的偏移量,也就是代表需要向右移動的位元組數
- whence :給offset引數一個定義,即表示要從哪個位置開始偏移,其僅有三個取值:0,1,2,0表示從檔案開頭開始算起,1表示從檔案當前指標位置開始算起,2表示從檔案末尾開始算起,如果不給whence,默認為0,
利用上述函式,我們可以輕松地解決前面作業中的寫入操作,代碼如下:
file = open('pi_digit.txt','r')
with open('result', 'w') as f: # 新生成的檔案名:result
f.write(file.read(2) + '\n') #寫入 “3.”
seek = 2 # 檔案指標位置
while seek <= 1000000:
file.seek(seek) # 移動至 “3.” 之后
seek += 100
f.write(file.read(100) + '\n') # 每隔100位換行
print("寫入完畢!")
file.close()
代碼執行完畢后,會在當前目錄生成一個 result.txt 檔案 ,
上述代碼里,我們使用了seek()函式強行控制檔案指標的指向,這樣便于在檔案讀取完畢后跳出while回圈,前面說過,執行read(100)后,檔案指標會向后移動100位,這樣看來也許可以不用seek()函式,小伙伴們可以思考一下,如果不使用seek()函式,如何實作寫入檔案的功能,
接著,我們來看看如何尋找某人的生日序列(yymmdd),圓周率神奇的地方就在于,任何人的生日都能在圓周率小數點后找到 ,在這,提供兩種方法:
1. 使用字串自帶的 index() 方法
呼叫方法:str1.index(str2),表示從字串str1中尋找子串str2,若找到,則回傳位置索引,否則會拋出錯誤----- ValueError ,呼叫時需小心使用,來看代碼實作,假設某人出生日是02年05月19日,有如下實作:
file = open('pi_digit.txt','r')
# 使用字串自帶的index()方法,此方法未找到會報錯ValueError,用try陳述句:
try:
index = file.read().index('020519')
print("'020519'位于小數點后",end = '')
print(index,end = '')
print('位,在新檔案中的行號為:',end = '')
row = (index - 2) // 100 + 2 # 根據索引位置計算行號
print(row)
except ValueError as e:
print("不存在")
file.close()
運行結果:

翻閱之前寫入生成的新檔案result.txt,找到第7678行,如下:

確實爬取到了我們要找的生日序列-----020519,
2. 使用正則運算式
熟悉正則運算式的小伙伴們也可以用正則運算式來爬取:
import re
file = open('pi_digit.txt','r')
# 也可以使用正則運算式獲取
pattern = re.compile(r'(020519)') # 出生日:02年05月19日
pi = re.search(pattern,file.read()) # 是否匹配
if pi:
index = pi.span(0)[0] # span()回傳匹配索引位置
print("'020519'位于小數點后", end='')
print(index, end='')
print('位,在新檔案中的行號為:', end='')
row = (index - 2) // 100 + 2 # 根據索引位置計算行號
print(row)
else:
print("不存在")
file.close()
同樣的運行結果:

值得注意的是,如果上述的寫入檔案操作和爬取生日序列操作同時運行時,可能會出現爬取生日序列失敗的情況,原因在于執行完檔案寫入操作后,檔案指標已經到了文本末尾,之后的爬取會從文本末尾開始,當然爬取不到任何東西了,可以在寫入檔案操作和爬取生日序列操作陳述句塊之間加上陳述句
“file.seek(0)”
將檔案指標指向文本開頭,這樣爬取便會從文本開頭開始:
import re
file = open('pi_digit.txt', 'r')
with open('result', 'w') as f: # 新生成的檔案名:result
f.write(file.read(2) + '\n') # 寫入 “3.”
seek = 2 # 檔案指標位置
while seek <= 1000000:
file.seek(seek) # 移動至 “3.” 之后
seek += 100
f.write(file.read(100) + '\n') # 每隔100位換行
print("寫入完畢!")
file.seek(0) # 將檔案指標重新指向文本開頭
# 方法一:使用字串自帶的index()函式獲取
try:
index = file.read().index('020519')
print("'020519'位于小數點后", end='')
print(index, end='')
print('位,在新檔案中的行號為:', end='')
row = (index - 2) // 100 + 2 # 根據索引位置計算行號
print(row)
except ValueError as e:
print("不存在")
# 方法二:使用正則運算式獲取
file.seek(0) # 將檔案指標重新指向文本開頭
pattern = re.compile(r'(020519)') # 出生日:02年05月19日
pi = re.search(pattern, file.read()) # 是否匹配
if pi:
index2 = pi.span(0)[0] # span()回傳匹配索引位置
print("'020519'位于小數點后", end='')
print(index2, end='')
print('位,在新檔案中的行號為:', end='')
row2 = (index2 - 2) // 100 + 2 # 根據索引位置計算行號
print(row2)
else:
print("不存在")
# 記得關閉pi_digit.txt檔案
file.close()
運行結果:
???????
此外,如果小伙伴們使用的IDE是 pycharm ,直接輸出圓周率100萬位,控制臺可能會缺失部分資料,原因在于pycharm對控制臺輸出空間做了最大值限制,打開設定,修改下圖紅框部分即可:
???????
最后,喜歡的小伙伴們點個贊鼓勵支持一下吧~
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/305962.html
標籤:java
