一、基本操作
基於字符的讀取(r),寫入(w)與追加(a)
1.mode='r'
f = open(file='文件讀取.txt', mode='r')
print(f.read())
2.mode='w'
f = open(file='文件寫入.txt', mode='w')
f.write('謝欣然 湖北 保密 保密')
write模式下,將數據寫入文件時,文件原有數據會被清空,即創建一個新文件以寫入數據
3.mode='a'
f = open(file='文件寫入.txt', mode='a')
f.write('xxr 湖北 保密 保密')
在文件close之前,寫入的數據暫時存在內存里,文件close之后才將數據追加到硬盤上。若不close文件,也可用flush刷新硬盤上的文件,此時新加入的數據已顯示在原來的文件數據之后。
4.打開文件時會出現的編碼錯誤
報錯:UnicodeDecodeError: 'gbk' codec can't decode byte 0xac in position 9: illegal multibyte sequence
原因:mac/linux系統編碼為utf-8,windows系統編碼為gbk,在Windows上打開mac/linux電腦傳過來的文件時,會出現文件編碼錯誤
解決方案:此時在代碼開頭加上# - - utf-8 - -並沒有用,需在open(file)中加上編碼方式encoding=utf-8
錯誤代碼:
f = open(file='文件錯誤.txt', mode='r')
print(f.read())
正確代碼:
f = open(file='文件錯誤.txt', mode='r', encoding='utf-8')
print(f.read())
二、區分read(), readline(), readlines()
1.read([size])
從文件的開始位置讀取size個字節的內容,如果read()中沒有帶參數的話那么就是讀取至整個文件結束,所以比較適合小型文件,把讀取的東西放在一個字符串中,返回的是一個字符串。
f = open(file='文件讀取.txt', mode='r')
print(f.read(10))
print('--------分隔符--------')
print(f.read())
f.close()
'''
輸出:
--------分隔符--------
廣州 173 50
喬亦菲 廣州 172 52
羅夢竹 北京 175 49
劉諾涵 北京 170 48
岳妮妮 廣州 177 54
賀婉萱 廣州 174 52
葉梓萱 上海 171 49
黑姑娘 河北 168 48
'''
2.readline()
readline讀取一行的意思,利用循環可以一行一行的讀取,比較適合大型文件成千上百行的那種,此方法返回一個字符串對象。
f = open(file='文件讀取.txt', mode='r')
print('--------分隔符--------')
lines = f.readline()
while lines:
print(lines.strip())
# print自帶換行
# strip用於移除字符串頭尾指定的字符(默認為空格或換行符)或字符序列。
lines = f.readline()
f.close()
'''
輸出:
--------分隔符--------
Alex馬大帥 廣州 173 50
喬亦菲 廣州 172 52
羅夢竹 北京 175 49
劉諾涵 北京 170 48
岳妮妮 廣州 177 54
賀婉萱 廣州 174 52
葉梓萱 上海 171 49
黑姑娘 河北 168 48
'''
3.readlines()
這個方法是讀取文件的所有行,把結果保存在一個列表(list)中,每一行都作為列表的一個元素,不適合讀取成千上萬行的文件,因為可能會卡死也會比較占內存。但讀取整個文件到一個迭代器方便我們遍歷(即讀取到一個list中,以供使用,比較方便)。
f = open(file='文件讀取.txt', mode='r')
print('--------分隔符--------')
print(f.readlines())
f.close()
'''
--------分隔符--------
['Alex馬大帥 廣州 173 50\n', '喬亦菲 廣州 172 52\n', '羅夢竹 北京 175 49\n', '劉諾涵 北京 170 48\n', '岳妮妮 廣州 177 54\n', '賀婉萱 廣州 174 52\n', '葉梓萱 上海 171 49\n', '黑姑娘 河北 168 48\n']
'''
補充:根據條件查詢文件信息
輸出:身高大於170,體重小於50的成員信息
f = open(file='文件讀取.txt', mode='r')
for line in f:
line = line.split()
height = int(line[2])
weight = int(line[3])
if height > 170 and weight < 50:
print(line)
f.close()
'''
['羅夢竹', '北京', '175', '49']
['葉梓萱', '上海', '171', '49']
'''
三、文件操作的其他功能
1.seek(offset)
把操作文件的光標移動到指定位置,返回值為None,即無返回值。
offset:開始的偏移量,也就是代表需要移動偏移的字節數。
注意:seek的長度是按字節算的,字符編碼存每個字符所占的字節長度不一樣。如漢字,用gbk存是2個字節一個字,用utf-8就是3個字節一個字。只能按整長度截取,否則報錯。
# 修改文件
f = open('文件寫入.txt', 'r+')
# 注意r+的添加是從當前指針開始添加,所以要添加到尾部
# 一定要f.read()從頭到尾讀一遍,不然就是從頭到為開始覆蓋
f.seek(2)
f.write('小新')
'''
此修改文件會對原文件進行覆蓋,即插入后會覆蓋之后的數據
'''
2.tell()
返回當前文件操作光標的位置
3.flush()
把文件從內存buffer里強制到硬盤。在文件close之前,寫入的數據暫時存在內存里,文件close之后才將數據追加到硬盤上。若不close文件,也可用flush刷新硬盤上的文件,此時新加入的數據已顯示在原來的文件數據之后。
4.os.rename與os.replace
關於Windows系統下,用os.rename替換文件時出現的坑:
import os
old_file = '修改文件.txt'
new_file = '修改文件2.txt'
f = open(file=old_file, mode='r', encoding='utf-8')
f_new = open(new_file, 'w')
old_str = '深圳'
new_str = '廣州'
for line in f:
if old_str in line:
line = line.replace(old_str, new_str)
f_new.write(line)
f.close()
f_new.close()
os.rename(new_file, old_file) # 此行錯誤
報錯:FileExistsError: [WinError 183] 當文件已存在時,無法創建該文件。: '修改文件2.txt' -> '修改文件.txt'
原因:Windows系統,在同一個文件夾內,無法命名一個相同文件名的文件。iOS與Linux可以直接重命名,並會替換掉之前的文件。
解決方案:將rename改為replace
5.占硬盤的方式修改文件
用占硬盤的方式修改文件可以不進行覆蓋,進行整體修改。如word,vim,不在硬盤上修改,把內容全部讀到內存里,數據可以在內存里增刪改查,修改之后,把內容再全部寫回硬盤,把原來的數據全都覆蓋掉。
old_file = '修改文件.txt'
new_file = '修改文件2.txt'
f = open(file=old_file, mode='r', encoding='utf-8')
f_new = open(new_file, 'w')
old_str = '深圳'
new_str = '廣州'
for line in f:
if old_str in line:
line = line.replace(old_str, new_str)
f_new.write(line)
f.close()
f_new.close()
此方法生成一個新文件“修改文件2”,存在硬盤里,若想覆蓋原文件:
import os
old_file = '修改文件.txt'
new_file = '修改文件2.txt'
f = open(file=old_file, mode='r', encoding='utf-8')
f_new = open(new_file, 'w')
old_str = '深圳'
new_str = '廣州'
for line in f:
if old_str in line:
line = line.replace(old_str, new_str)
f_new.write(line)
f.close()
f_new.close()
os.replace(new_file, old_file)
6.sys argv[]
sys argv[]是一個從程序外部獲取參數的橋梁,即從終端(命令行)獲取參數。從外部取得的參數可以是多個,所以獲得的是一個列表(list),也就是說sys.argv其實可以看作是一個列表,所以才能用[]提取其中的元素。 其第一個元素是程序本身,隨后才依次是外部給予的參數。
import sys
print(sys.argv)
從Pycharm的Terminal終端輸入輸出結果:
'''
C:\Users\Administrator\Desktop\新建文件夾>python 4.py
['4.py']
C:\Users\Administrator\Desktop\新建文件夾>python 4.py Hello world!
['4.py', 'Hello', 'world!']
'''
7.open with告別文件開關繁瑣操作
文件用open打開后就一定要關閉(close),而使用with打開就可以不需加上close。
原代碼:
file = open('1.txt', 'w')
file.write('簡單明了,省時省力')
file.close()
改進后的代碼:
with open('1.txt', 'w') as file:
file.write('簡單明了,省時省力')
open也可進行多個文件的同時打開:
with open('a.txt','r',encoding='utf-8') as f,open('b.txt') as f1:
f.write('簡單明了,省時省力')
f1.write('簡單明了,省時省力')