python 3 之檔案操作
檔案操作
1.檔案處理的流程
1)開啟檔案,得到檔案控制代碼並賦值給一個變數
2)通過控制代碼對檔案進行操作
3)關閉檔案
能呼叫方法的一定是物件
li=[1,2,3]
li.append('2')
'asc'.capitalize()
例如:
f = open('chenli.txt') #開啟檔案
first_line = f.readline()
print('first line:',first_line) #讀一行
data = f.read()# 讀取剩下的所有內容,檔案大時不要用
print(data) #列印讀取內容
f.close() #關閉檔案
2.檔案操作基本用法
1)基本用法:
file_object = open(file_name, access_mode = ‘r’, buffering = -1)
open函式有很多的引數,常用的是file_name,mode和encoding
file_name:開啟的檔名,若非當前路徑,需指出具體路徑
access_mode檔案開啟模式
buffering的可取值有0,1,>1三個,0代表buffer關閉(只適用於二進位制模式),1代表line buffer(只適用於文字模式),>1表示初始化的buffer大小;
encoding表示的是返回的資料採用何種編碼,一般採用utf8或者gbk;
2)檔案開啟模式
r ,只讀模式【預設模式,檔案必須存在,不存在則丟擲異常】
w,只寫模式【不可讀;不存在則建立;存在則清空內容】
x, 只寫模式【不可讀;不存在則建立,存在則報錯】
a, 追加模式【可讀; 不存在則建立;存在則只追加內容】,檔案指標自動移到檔案尾。
"+" 表示可以同時讀寫某個檔案
r+, 讀寫【可讀,可寫】
w+,寫讀【可讀,可寫】,消除檔案內容,然後以讀寫方式開啟檔案。
x+ ,寫讀【可讀,可寫】
a+, 寫讀【可讀,可寫】,以讀寫方式開啟檔案,並把檔案指標移到檔案尾。
"b"表示以位元組的方式操作,以二進位制模式開啟檔案,而不是以文字模式。
rb 或 r+b
wb 或 w+b
xb 或 w+b
ab 或 a+b
注:以b方式開啟時,讀取到的內容是位元組型別,寫入時也需要提供位元組型別,不能指定編碼
import time
三種基本的操作模式 r(只可讀) w(只可寫) a(追加)
流程:1 建立檔案物件'小重山2' 2 呼叫檔案方法進行操作 3 關閉檔案
data=open('小重山2','r',encoding='utf8').read()
print(data)
'r'表示讀模式 encoding='utf8'表示轉換字元 read()讀操作 ()內是幾就讀取幾個字元,不新增內容就是預設讀取全部內容
f=open('小重山2','r',encoding='utf8')
data=f.read(5)
print(data)
補充:
python中有三個方法來處理檔案內容的讀取:
read() #一次讀取全部的檔案內容。
readline() #每次讀取檔案的一行。
readlines() #讀取檔案的所有行,返回一個字串列表。
print(f.readable()) #判斷檔案是否是r模式開啟的
print(f.closed) #判斷檔案是否是關閉狀態
python中在文字檔案內容移動的操作
file.seek(offset,whence=0) #從檔案中給移動指標,從whence(0起始,1當前,2末尾)偏移offset個位元組,正往結束方向移動,負往開始方向移動
file.tell() #返回當前檔案中的位置。獲得檔案指標位置
file.truncate(size=file.tell()) #擷取檔案到最大size個位元組,預設為當前檔案位置
上述操作等於
data=open('小重山2','r',encoding='utf8')
f=data.read()
print(f)4
f=open('小重山2','r',encoding='utf8')
f.write()#報錯
f.close()
讀寫模式必須一致,如下
f=open('小重山2','w',encoding='utf8')
f.write('hello world')
f.close()
補充:
以w方式寫入檔案
f=open('a.txt','w',encoding='utf-8')
# f=open('b.txt','r',encoding='utf-8') #以讀的方式開啟檔案,檔案不存在則報錯
f=open('b.txt','w',encoding='utf-8')
# print(f.writable())
f.write('111111\n22222222')
f.seek(0)
f.write('\n333333\n444444')
f.writelines(['\n55555\n','6666\n','77777\n'])
f.close()
a.txt 為空
b.txt
333333
444444
55555
6666
77777
file.write(str) #向檔案中寫入字串(文字或二進位制)
file.writelines(seq) #寫入多行,向檔案中寫入一個字串列表,注意,要自己加入每行的換行符
file.flush() #重新整理檔案內部緩衝,直接把內部緩衝區的資料立刻寫入檔案, 而不是被動的等待輸出緩衝區寫入.
注:當開啟的物件不存在時,會自動建立物件,存在時會先將物件格式化在寫內容
在第二遍執行寫操作時將不會再次格式化 而是直接緊跟在後面接著列印 若想換行或者空格 操作如下
f.write('hello world \n')
若想對物件新增內容且不格式化原有內容可執行操作如下
f=open('小重山2','a',encoding='utf8') #'a'表示append追加之意
f.write('\nhello world \n')
f.write('hel')
f.close() 注意:if not close,資料會快取,而不是磁碟!
在對一個物件執行操作時 兩個程式可同時對同一個檔案執行操作,但 注意:程式程式結尾必須新增close 因為不知道程式什麼時候幫你執行結束,程式結束才會將資料提交到磁碟
f=open('小重山2','r',encoding='utf8')
f.write('\nhello world \n')
f.write('alex')
#注意:if not close,資料會快取,而不是磁碟!
time.sleep(30) #讓程式執行30S
f.close()
若對檔案中間進行插入可執行如下
data=open('小重山2','r',encoding='utf8')
number = 0
for i in data:
number += 1
if number == 6:
i = ''.join([i.strip(), 'iiiii']) # 取代萬惡的+
print(i.strip())
f.close()
或者:
data=open('小重山2','r',encoding='utf8')
number = 0
for i in data:
number += 1
if number == 6:
print(i.strip(),'qqq')
eslse
print(i.strip())
f.close()
但現實中不這樣實現,因為如果檔案過大不能將檔案 放置記憶體處理
##########對於大資料檔案,要用以下方式(the best way):
# number=0
# for i in f:#這是for內部將f物件做成一個迭代器,用一行去一行。
# number+=1
# if number == 6:
# i = ''.join([i.strip(), 'iiiii']) # 取代萬惡的+
# # print(i.strip())
# print(i.strip())
tell命令:與seek命令
# print(f.tell())# 取出游標位置,
# print(f.read(2))
# print(f.tell()) #其中read中如果有中文則一箇中文會被識別為三個游標位
#
# f.seek(0)# 移動游標到指定的位置
# print(f.read(4))
flush命令:
#flush():同步吧將資料從快取轉移到磁碟上去
##進度條例項
# import sys,time
# for i in range(30):
# sys.stdout.write("*")
# sys.stdout.flush()
# time.sleep(0.1)間隔0.1S輸出一個程式結果
或者:
#print的flush
# import sys,time
# for i in range(30):
# print('*',end='',flush=True) #將flush作為一個引數使用
# time.sleep(0.1)
上下文管理with語句
當你做檔案處理,你需要獲取一個檔案控制代碼,從檔案中讀取資料,然後關閉檔案控制代碼。
正常情況下,程式碼如下:
file = open("/tmp/foo.txt")
data = file.read()
file.close()
這裡有兩個問題。一是可能忘記關閉檔案控制代碼;二是檔案讀取資料發生異常,沒有進行任何處理。
然而with可以很好的處理上下文環境產生的異常。下面是with版本的程式碼:
with open("/tmp /foo.txt") as file:
data = file.read()
with的基本思想是with所求值的物件必須有一個__enter__()方法,一個__exit__()方法。緊跟with後面的語句被求值後,返回物件的__enter__()方法被呼叫,這個方法的返回值將被賦值給as後面的變數。當with後面的程式碼塊全部被執行完之後,將呼叫前面返回物件的__exit__()方法。
#with 同時管理多個檔案物件
# with open('log1','r') as f_read, open('log2','w') as f_write:
# for line in f_read:
# f_write.write(line)
補充:
模擬 tail -f access.log
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# tail -f access.log
import time
with open('access.log','r',encoding='utf-8') as f:
f.seek(0,2)
while True:
line=f.readline().strip()
if line:
print('新增一行日誌',line)
time.sleep(0.5)