10.檔案操作

jason8826發表於2024-05-10
import os
# __file__
print("檔案絕對路徑(含檔名)",__file__)

# os.getcwd()
print("獲取絕對路徑(不含檔名)",os.getcwd())

# os.path.abspath(path)
print("獲取相對路徑的絕對路徑",os.path.abspath("."))

# os.path.isabs(path)
print("判斷引數是否為絕對路徑",os.path.isabs(os.getcwd()))

# os.path.relpath(path,start)
print("返回從start路徑到path路徑的相對路徑",os.path.relpath("C:\\ORA","."))

# os.path.dirname(path),os.path.basename(path),os.path.split(path)
path1 = __file__
print("獲取檔案路徑",path1)
print("返回路徑",os.path.dirname(path1))
print("返回檔名",os.path.basename(path1))
print("同時返回路徑和檔名到一個元組中",os.path.split(path1))

# os.path.exists(path),os.path.isdir(path),os.path.isfile(path)
print("判斷路徑或檔案是否存在",os.path.exists(path1))
print("判斷path是否為路徑",os.path.isdir(path1))
print("判斷path是否為檔案",os.path.isfile(path1))

# os.remove(),刪除檔案
# os.remove("a.txt")

# file = open(file_name [, mode='r' [ , buffering=-1 [ , encoding = None ]]])
# mode:預設"r"只讀
# buffering:是否使用緩衝區,預設-1代表使用預設的緩衝區大小
# encoding:編碼格式,預設cp936(即GBK編碼)
f1 = open('module_test.py') # 以預設方式開啟檔案
print("輸出檔案是否已經關閉",f1.closed)
print("輸出訪問模式",f1.mode)
print("輸出編碼格式",f1.encoding)
print("輸出檔名",f1.name)
f1.close()

# file.read([size]),逐位元組或字元讀取檔案(size省略,則一次性讀取所有內容)
f2 = open("module test.py",encoding = "utf-8")
print("讀取10個字元",f2.read(10))
print("讀取整個檔案",f2.read())
f2.close()
# file.readline([size]),逐行讀取檔案(size用於讀取每一行時,一次最大讀取的字元或位元組數)
f3 = open("module test.py",encoding = "utf-8")
print("讀取一行",f3.readline())
f3.close()
# file.readlines(),一次性讀取多行,與read()類似,只不過返回一個字串列表,每個元素為檔案中的一行內容
f4 = open("module test.py",encoding = "utf-8")
for i in f4.readlines():
    print("for迴圈輸出readlines()",i)
f4.close()

# file.write(string)
f5 = open("test.txt","w")
f5.write("寫入一行資料")
f5.flush() # 檔案寫入資料後,不想馬上關閉檔案,可以呼叫flush()函式,將緩衝區的資料寫入檔案中
f5.close()
# file.writelines([str])
# [str]:字串序列
r = open("module test.py")
w = open("test.txt","w")
w.writelines(r.readlines()) # writelines()寫入資料時,不會自動換行。這個地方換行是因為readlines()讀的資料帶換行符
r.close()
w.close()

# file.tell()和file.seek(offset[,whence])
# whence:指定檔案指標位置,0:檔案頭(預設),1:當前位置,2:檔案尾
# offset:相對於whence的偏移量,正數向後偏移,負數向前偏移(offset為負數時,檔案必須以二進位制格式開啟)
f6 = open("module test.py")
f6.seek(3)
print("seek後的位置",f6.tell()) # 讀取檔案指標當前位置
print("從seek後的位置讀整行:",f6.readline())

# with as,確保語句執行完畢後,自動關閉已經開啟的檔案(哪怕檔案操作期間出現異常也會關掉)
'''格式:
with 表示式 [as target]: # target用於接收表示式的返回
    程式碼塊'''
with open("test.txt","w") as f:
    f.write("with as開啟檔案輸入值")

# 序列化pickle庫,實現python物件的持久化儲存
# dumps():將python中的物件序列化成二進位制物件,並返回
# loads():讀取給定的二進位制物件資料,並轉換成python物件
# dump():將python中的物件序列化成二進位制物件,並寫入檔案
# load():讀取指定的序列化資料檔案,並返回物件(侷限性:不適合讀取海量資料)
import pickle
in1 = ['111','2222','3333']
out1 = pickle.dumps(in1)
print('python物件轉換成二進位制物件',out1)
in1 = pickle.loads(out1)
print('二進位制物件轉換成python物件',in1)
with open('test_pickle.txt','wb') as f:
    pickle.dump(in1,f) # 將物件轉換成二進位制物件,寫入檔案
with open('test_pickle.txt','rb') as f:
    out1 = pickle.load(f) # 讀取序列化檔案(侷限性:不適合讀取海量資料)
    print(out1)

# fileinput模組,逐行讀取多個檔案
# 格式:fileinput.input(files="file1, filen2, ...", inplace=False, backup='', bufsize=0, mode='r', openhook=None)
# files:多個檔案的路徑列表;
# inplace:用於指定是否將標準輸出的結果寫回到檔案,此引數預設值為 False;
# backup:用於指定備份檔案的副檔名;
# bufsize:指定緩衝區的大小,預設為 0;
# mode:開啟檔案的格式,預設為 r(只讀格式);
# openhook:控制檔案的開啟方式,例如編碼格式等
import fileinput
files = ['module_test.py','test.txt']
for line in fileinput.input(files): # 讀取檔案內容的次序,按照檔名的先後次序,讀完一個再讀另一個
    print('fileinput讀取檔案',line)
fileinput.close()

# linecahce模組,讀取指定檔案中指定行(只能以utf-8讀取檔案)
import linecache
print('linecache讀取指定行(讀第一行)',linecache.getline('10.檔案操作.py',1))

# pathlib模組
# UNIX 系統路徑使用的分隔符是斜槓(/),而 Windows 使用的是反斜槓(\)
from pathlib import *
path1 = PurePath('d','test.txt')
path2 = PurePosixPath('d','test.txt')
print('PurePath',path1)
print('PurePosixPath',path2)

# os.path模組
from os import path
print('獲取絕對路徑',path.abspath('test.txt'))
print('獲取共同字首',path.commonprefix(['C://my_file.txt', 'C://a.txt']))
print('獲取共同路徑',path.commonpath(['http://c.biancheng.net/python/', 'http://c.biancheng.net/shell/']))
print('獲取目錄',path.dirname('C://my_file.txt'))
print('判斷指定目錄是否存在',path.exists('my_file.txt'))

# fnmatch模組
# fnmatch.filter(names, pattern):對 names 列表進行過濾,返回 names 列表中匹配 pattern 的檔名組成的子集合。
# fnmatch.fnmatch(filename, pattern):判斷 filename 檔名,是否和指定 pattern 字串匹配
# fnmatch.fnmatchcase(filename, pattern):和 fnmatch() 函式功能大致相同,只是該函式區分大小寫。
# fnmatch.translate(pattern):將一個 UNIX shell 風格的 pattern 字串,轉換為正規表示式
import fnmatch
#filter()
print(fnmatch.filter(['dlsf', 'ewro.txt', 'te.py', 'youe.py'], '*.txt'))
#fnmatch()
for file in ['word.doc','index.py','my_file.txt']:
    if fnmatch.fnmatch(file,'*.txt'):
        print(file)
#fnmatchcase()
for file in ['word.doc','index.py','my_file.txt','a.TXT']:
    if fnmatch.fnmatchcase(file, '*.txt'):
        print(file)
#translate()
print(fnmatch.translate('a*b.txt'))

# tempfile模組,生成臨時檔案和臨時目錄
# 方式一、手動建立臨時檔案,讀寫臨時檔案後需要主動關閉它,當程式關閉該臨時檔案時,該檔案會被自動刪除。
# 方式二、使用 with 語句建立臨時檔案,這樣 with 語句會自動關閉臨時檔案。
import tempfile
# 建立臨時檔案
fp = tempfile.TemporaryFile()
print(fp.name)
fp.write('兩情若是久長時,'.encode('utf-8'))
fp.write('又豈在朝朝暮暮。'.encode('utf-8'))
# 將檔案指標移到開始處,準備讀取檔案
fp.seek(0)
print(fp.read().decode('utf-8')) # 輸出剛才寫入的內容
# 關閉檔案,該檔案將會被自動刪除
fp.close()
# 透過with語句建立臨時檔案,with會自動關閉臨時檔案
with tempfile.TemporaryFile() as fp:
    # 寫入內容
    fp.write(b'I Love Python!')
    # 將檔案指標移到開始處,準備讀取檔案
    fp.seek(0)
    # 讀取檔案內容
    print(fp.read())
# 透過with語句建立臨時目錄
with tempfile.TemporaryDirectory() as tmpdirname:
    print('建立臨時目錄', tmpdirname)