一. 操作檔案的三個步驟: 開啟檔案, 讀寫, **os資源
1. 方式一: 開啟檔案, 讀寫, **os資源
f = open(r"y:\new\a.txt", mode="rt", encoding="utf-8") # t讀寫檔案的格式為字串,open返回值檔案物件/檔案控制代碼,是程式的變數值
data = f.read() # 硬碟上的檔案內容讀到記憶體中,os根據指定的encoding把二進位制數轉成t(unicode字串)給程式,t僅限文字檔案
print(data, type(data))
f.close() # close**os資源,close後不能再read,檔案物件是程式的變數值,是程式的資源,仍然存在
2. 方式二: 上下文管理 with 會自動呼叫f.close(), f1.close(), f2...
with open(r"y:\new\a.txt", mode="rt", encoding="utf-8") as f, \
open(r"y:\new\b.txt", mode="rt", encoding="utf-8") as f1:
pass # 也可以用...
二. 檔案的開啟模式
1. 控制檔案讀寫操作的模式: r唯讀, w只寫,擦寫, a只追加寫, +加上原沒有的操作, r+, w+, a+: 讀寫
1.1 r: 唯讀, 不可寫, 預設模式, 指標在檔案開頭
with open(r"y:\new\a.txt", mode="rt", encoding="utf-8") as f:
print(f.readable()) # true
print(f.writable()) # false
1.2 w: 只寫, 不可讀, 建立乙個新文件, 同名檔案不存在則為建立, 同名檔案存在則覆蓋, 指標跳到檔案開頭
with open(r"y:\new\b.txt", mode="wt", encoding="utf-8") as f:
f.write("你好\nhello world.")
f.write("開啟檔案不關的情況下,指標跟著移動,後續新寫入的內容則是追加.但是檔案關了重新開啟,再寫=擦寫")
1.3 a: 只追加寫,不可讀,檔案不存在則新建乙個空檔案;檔案存在則不清空,無論是不是重新開啟或關了,檔案指標都跳到檔案末尾,追加寫入新內容
1.4 r+, w+, a+: 讀寫
2. 控制檔案讀寫內容的模式, t,b須和r,w,a連用
2.1 t: 預設, 文字格式, 讀寫都是str字串, 數字不可以, 僅限文字檔案, 必須指定encoding引數
2.2 b: 原生格式, 讀寫都是bytes為單位, 能用於所有檔案, 一定不能指定encoding引數
with open(r"y:\new\a.txt", mode="wb") as f:
f.write("原生格式寫入新內容".encode("utf-8"))
3. 案例: 檔案copy程式
src_file = input("原始檔路徑: ").strip()
dst_file = input("目標檔案路徑: ").strip()
with open(r"%s" % src_file, mode="rb") as f1, \
open(r"%s" % dst_file, mode="wb") as f2:
3.1 方法一: 一次性讀入記憶體
data = f1.read()
f2.write(data)
3.2 方法二: 逐行讀取寫入
for line in f1:
f2.write(line)
三. 檔案內指標移動: seek是無io操作的移動, read是有io操作的被動移動
file.seek(移動的位元組個數, 三種模式) # 3種模式都以位元組為移動單位
1. 三種模式:
1.1 模式 0 : 從檔案開頭為起點,f.seek(3, 0)從頭往右移動3個位元組
1.2 模式 1 : 從當前指標所在的位置,f.seek(6, 1)前面停在第3位元組,現停在第9位元組
1.3 模式 2 : 從檔案末尾為起點,f.seek(-6, 2)從末尾往左移6位元組,正數右移,負數左移
2. 三種模式適用範圍:
2.1 mode="t"模式: seek只能用 模式 0, 而另一種移動read(n)中n,只有mode="t"模式下,代表字元個數
with open(r"y:\new\a.txt", mode="rt", encoding="utf-8") as f: # 檔案內容:hello你好
print(f.read(6)) # 列印: hello你 ,以字元為單位,中英文都是乙個字元
2.2 mode="b"模式: seek都可用 模式 0, 1, 2, seek和read(n)中n都代表位元組個數
with open(r"y:\new\a.txt", mode="rb") as f: # 檔案內容:hello你好
print(f.read(6)) # 列印: b'hello\xe4' ,以位元組為單位,utf-8中,中文3位元組,英文1位元組
f.seek(0, 2) # 指標跳到末尾
print(f.tell()) # tell獲取從檔案開頭到當前位置的總位元組數
3. 示例: 模擬寫tail -f access.log
3.1 測試程式寫入日誌
import time
with open('access.log', mode='at', encoding='utf-8') as f:
f.write("%s %s\n" % (time.strftime("%y-%m-%d %h:%m:%s %p"), "程式寫的日誌內容"))
3.2 模擬寫tail -f 檢視日誌
import time
with open('access.log', mode='rb') as f:
f.seek(0, 2)
while true:
line = f.readline() # readline每次讀一行
if len(line) == 0: # 沒有日誌的時候, 稍微等待, 減少負載開銷
time.sleep(0.5) # 死迴圈會不停呼叫,負載會公升高
else:
print(line.decode('utf-8'), end='') # 原日誌中\n,列印預設也有,會有兩個\n去掉乙個
四. 操作檔案的方法
1. f.read(n) 從當前位置讀到末尾,只有mode="t"模式下,read(n)中n代表字元個數
2. f.readlines() rt模式,以行為單位讀取文字,存入列表['hello你好\n','l2\n','l3']
3. f.writelines("hello") wt模式, 迴圈分別寫入5個字母, 而f.write("hello")一次寫入
with open(r"y:\new\a.txt", mode="wt", encoding="utf-8") as f:
lines = ["aa\n", "bb\n", "cc\n"]
for line in lines: # 這兩行效果等於f.writelines(lines), 實質就是for迴圈取值
f.write(line)
4. f.flush() 記憶體資料刷入硬碟
5. f.truncate(size) 截斷,從開頭保留n個位元組,後面全刪,是寫操作,故要r+,a模式
with open(r"y:\new\a.txt", mode="r+t", encoding="utf-8") as f:
f.truncate(3)
五. 修改檔案的方式
1. 方式一: 硬碟檔案一次性讀入記憶體, 記憶體中修改完, 再覆蓋原檔案,不額外占用硬碟空間, 過多占用記憶體
with open(r"y:\new\a.txt", mode="rt", encoding="utf-8") as f1:
data = f1.read()
res = data.replace("source", "target")
with open(r"y:\new\a.txt", mode="wt", encoding="utf-8") as f2:
f2.write(res)
2. 方式二: 逐行讀原始檔,記憶體中修改後,逐行寫入臨時檔案,刪除源,臨時檔案重新命名,額外占用硬碟空間, 節省記憶體
import os
with open(r"y:\new\a.txt", mode="rt", encoding="utf-8") as f1, \
open(r"y:\new\.a.txt.swp", mode="wt", encoding="utf-8") as f2:
for line in f1:
f2.write(line.replace("source", "target"))
os.remove(r"y:\new\a.txt")
os.rename(r"y:\new\.a.txt.swp", r"y:\new\a.txt")
Python之批量建立檔案
批量建立檔案其實很簡單,只需要按照需要建立寫檔案 寫完關閉當前寫檔案 建立新的寫檔案 寫完關閉當前檔案 不斷迴圈即可,以下是乙個簡單例子,將大檔案big.txt按照每1000行分割成乙個個小檔案,具體做法如下 coding utf 8 index 0 count 0 f in open d.txt ...
python讀寫 建立 檔案(一)
python中對檔案 資料夾 檔案操作函式 的操作涉及到os模組和shutil模組。得到當前工作目錄,即當前python指令碼工作的目錄路徑 os.getcwd 返回指定目錄下的所有檔案和目錄名 os.listdir 函式用來刪除乙個檔案 os.remove 刪除多個目錄 os.removedirs...
Python 建立資料夾
def mkdir path 引入模組 import os 去除首位空格 path path.strip 去除尾部 符號 path path.rstrip 判斷路徑是否存在 存在 true 不存在 false i ists os.path.exists path 判斷結果 ifnot i ists ...