001.00 一般檔案處理

Jason990420發表於2019-08-01
建檔日期: 2019/07/28
更新日期: 2020/03/28 錯誤更正, 增加路徑名的脫離字元的說明
Win 10 Python 3.7.4
檔案目錄:
- Script(.py)檔案位置: D:/Python_Work/001.00 文字檔案處理
- 文字/二進位制檔案位置: D:/Python_Work/001.00 文字檔案處理/文字檔案
- 圖形檔案: D:/Python_Work/001.00 文字檔案處理/圖形檔案/
# 檔名: 001.00 一般檔案處理.py
# 預備: 檔案001.txt以unicode存檔, 檔案002.txt以ANSI存檔
# 檔案內容, 印在console上.
# 檔名變數
filename1 = 'D:/Python_Work/001.00 一般檔案處理/一般檔案/一般檔案001(unicode).txt'
filename2 = 'D:/Python_Work/001.00 一般檔案處理/一般檔案/一般檔案002(ansi).txt'

# 定義檔案列印函式
def print_all(filename, codec):
    fn = open(filename, encoding=codec)
    data = fn.read()
    print(data)
    fn.close()
print_all(filename1, "utf_16")
print("")
print_all(filename2, "mbcs") 

1. 資料檔名稱字串

  • 相對路徑: "一般檔案/一般檔案001.txt"
  • 絶對路徑: “D:/Python_Work/001.00 一般檔案處理/一般檔案/一般檔案001.txt”

分隔符可以使用/\\, 但在Python中, \為脫離符, 所以使用\, 必須為\\. 幾種表示方式, 如

  • 'd:\\test.txt'
  • 'd:/test.txt'
  • r'd:\test.txt', r代表raw, \不會被當作脫離符

2. 開啟檔案

  • fileobj = open(filename, access_mode=’r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

    • filename: 檔名字串

    • access_mode: 訪問模式, 預設為只讀’r’, 不衝突的模式可以組合一起

      • r - 只讀模式 (Read Mode)
      • w - 寫入新檔案 (Write Mode)
      • x - 獨佔檔案, 不存在則出錯
      • a - 附加新資料
      • b - 二進位制檔案 (Binary Mode)
      • t - 文字檔案 (Text Mode)
      • + - 可讀可寫
      • 常用的引數只有”r”, “w”, “t”及”b”, 也就是二進位制檔案/文字檔案, 讀/寫, 四者混用.
    • buffering: 0-沒緩衝(只有b模式可用), 1-行緩衝(只有t模式可用), >1-緩衝區大小, <0-系統預設, b模式下為io.DEFAULT_BUFFER_SIZE, 典型值為4096或8192 bytes; t模式下, 交談式文字檔案, isatty()是True, 則為行緩衝, 否則如b模式一樣

    • encoding: 僅供文字檔案使用, 總共至少有113種編碼, 比如’ascii’, ‘big5’, ‘big5hkscs’, ‘gbk’, ‘gb18030’, ‘hz’, ‘utf_8’, ‘utf_16’等等. 一定要確定檔案格式, 否則會讀不進資料, 比如記事本中可以存成四種不同格式的txt檔, ansi(mbcs), Unicode (utf_16), Unicode Big endian (utf_16_be)以及UTF-8(utf_8).

    • errors: coding/encding錯誤時的處理程式

      • 'strict': 編碼錯誤,則引發ValueError異常。預設值None具有相同的效果。
      • 'ignore': 忽略編碼錯誤可能會導致資料丟失。
      • 'replace': 導致在有錯誤資料的地方插入替換標記。<<< 待確認 >>>
      • 'surrogateescape': 任何不正確的位元組,將被轉回到相同的位元組中。這對於處理未知編碼的檔案很有用。
      • 'xmlcharrefreplace': 寫入時才有用,編碼不支援的字元將替換為&#nnn;。
      • 'backslashreplace': 用Python的反向轉義序列替換格式錯誤的資料。
      • 'namereplace': 寫入時才有用,用\ N {…}轉義序列替換不支援的字元。
    • newline:

      • 讀入模式時: None: ‘\n’, ‘\r’, or ‘\r\n’會被轉換成’\n’; 空字串:不處理; ‘其他’: 則只取回不含’其他’的字串.
      • 寫出模式時: None: ‘\n’會被轉換為os.linesep; “”/‘\n’不處理; ‘其他’: 則直接替換.
    • closefd: 如果closefd為False並且給出了檔案描述符而不是檔名,則在關閉檔案時,底層檔案描述符將保持開啟狀態。如果給出檔名,則closefd必須為True(預設值),否則將引發錯誤。<<< 待確認 >>>

    • opener: 透過傳遞可呼叫的開啟者可以使用自定義開啟器。 然後透過使用(file,flags)呼叫opener來獲取檔案物件的基礎檔案描述符。 opener必須返回一個開啟的檔案描述符(傳遞os.open作為opener導致類似於傳遞None的功能)。<<< 待確認 >>>

3. 關閉檔案 fileobj.method()

  • close() 重新整理緩衝區資料後, 關閉檔案

4. 檔案屬性 fileobj.method()

  • closed() 檔案已關閉? True / False
  • mode() 檔案訪問模式access mode
  • name() 檔名
  • softspace() 輸出後沒加一個空格 ? True / False

5. 檔案讀取 fileobj.method()

  • read([size]) 讀入位元組數, 省略則全部讀入, 檔案太大就不太合適.
  • readline() 一行一行讀, 佔記憶體少, 不過比較慢. 每一行字串最後會帶有’\n’, 最後一行可能沒有’\n’, 可以使用line.strip(‘\n’)處理. print(‘\n’)會產生兩空行, 可以使用print(“”)
  • readlines() 讀出字串, 組成一個list, 佔記憶體多, 不過比較快.
  • linecache.method() 僅適用於ASCII或utf-8的檔案, 耗記憶體;
    • getline(filename, lineno[, module_globals=None]) 讀入第幾行.
    • getlines(filename) 全部讀入list中.
    • clearcache() 清除快取
    • checkcache(filename=None) 檢查(所有)檔案的快取
    • lazycache(filename[, module_globals=None]) 捕捉足夠資訊供使用
    • updatecache(filename) 更新快取, 同時更新getlines的list內容
# 檔名: 001.01 一般檔案處理.py
# readline(), readlines(),linecache.getline(),linecache.getlines() 用法

import linecache

# 檔名變數
filename1 = 'D://Python_Work//001.00 一般檔案處理// 一般檔案// 一般檔案001(unicode).txt'
filename2 = 'D://Python_Work//001.00 一般檔案處理// 一般檔案// 一般檔案002(ansi).txt'
filename3 = 'D://Python_Work//001.00 一般檔案處理// 一般檔案// 一般檔案003(utf-8).txt'

# readline()用法 -- string
fn=open(filename1,encoding='utf_16')
line = fn.readline()
while line:
    print(line.strip('\n'))
    line = fn.readline()
fn.close()
print('')

# readlines()用法 -- list
fn=open(filename2,encoding='mbcs')
lines = fn.readlines()
for line in lines:
    print(line.strip('\n'))
fn.close()
print("")

# linecache.getlines() 用法 -- 不用open, 直接讀全部, 僅適用於ASCII或utf-8
lines = linecache.getlines(filename3)
for line in lines:
    print(line.strip('\n'))
linecache.clearcache()
print("")

# linecache.getline() 用法 -- 不用open, 直接讀某一行, 僅適用於ASCII或utf-8
# 文字檔案有9for lineno in range(1,10):
    line = linecache.getline(filename3,lineno)
    print(line.strip('\n'))

6. 寫入檔案 fileobj.method()

  • write(string) 寫入字串, 不會自動加’\n’
  • writelines(list) 寫入整個字串list, 不會自動加’\n’
  • seek(offset[, whence]) 跳過offset個, 正值向前, 負值向後, whence 0表示從頭開始, 1表示目前位置, 2表示最後位置. 有特別格式的檔案, 不能跳offset, 不然譯碼器無法解析檔案的編碼格式作讀取, 將造成錯誤, 最好是二進位制檔案.
  • flush() 更新緩衝區, 一般檔案關閉後會自動更新.
  • tell() 指出目前檔案內容指標位置.
  • fileno() 返回整數值的檔案描述符, 類似open()返回值, 供OS檔案操作使用.
  • isatty() 是否為TTY裝置? True or False, TTY:使用者輸入輸出裝置, 非檔案.
  • next() 返回下一行. 檔案剛開啟時, 則為第一行.
  • truncate([size]) 把檔案size後的內容刪除, 沒size, 則從目前位置起刪除. 只讀模式不能用.
# 檔名: 001.02 一般檔案處理.py
# writeline() & writelines() 用法
# 檔名變數
filename1 = 'D:/Python_Work/001.00 一般檔案處理/ 一般檔案/ 一般檔案001(unicode).txt'
filename2 = 'D:/Python_Work/001.00 一般檔案處理/ 一般檔案/ 一般檔案001(unicode)_rev1.txt'
filename3 = 'D:/Python_Work/001.00 一般檔案處理/ 一般檔案/ 一般檔案001(unicode)_rev2.txt'

with open(filename1, 'r', encoding='utf_16') as fileobj_read:
    # Note: readlines doesn't trim the line endings
    lines = fileobj_read.readlines()

with open(filename2, 'w') as fileobj_write1:
    fileobj_write1.writelines(lines)

with open(filename3, 'w') as fileobj_write2:
    for line in lines:
        fileobj_write2.write(line)

fileobj_read.close()
fileobj_write1.close()
fileobj_write2.close()
# 檔名: 001.03 一般檔案處理.py
# write() 用法
filename1 = "圖形檔案/圖形檔案001.jpg"
filename2 = "圖形檔案/圖形檔案001_bak.jpg"

fileobj_read = open(filename1,"rb")
file = fileobj_read.read()

fileobj_write = open(filename2, "wb")
fileobj_write.write(file)

~ The End ~

本作品採用《CC 協議》,轉載必須註明作者和本文連結
Jason Yang

相關文章