1 打開文件
文件操作步驟:
1、打開文件獲取文件的句柄,句柄就理解為這個文件
2、通過文件句柄操作文件
3、關閉文件。
1.1 打開方法
f = open('xxx.txt') #需f.close()關閉文件
f = open(r'E:\PycharmProjects\Python3_study\Day3\n文件讀寫',encoding='utf-8') #'r'可以防止字符串在使用的時候不被轉義
with open(<filename>,<mode>) as f1,open(<filename>,<mode>) as f2: #文件使用結束后自動關閉文件
1.2 打開模式
- a+
1 f = open('test.txt','a+', encoding = 'utf-8') 2 f.seek(0) #指針在末尾,需要將其移至開頭 3 print(f.read()) #讀出所有內容

1 hello world 2 你好,世界
- w+
1 f = open('test.txt','w+', encoding = 'utf-8') 2 f.seek(0) 3 print(f.read()) #發現原來的內容已清空 4 f.write('這是新的') 5 f.seek(0) 6 print(f.read()) #可以讀到剛剛寫入的內容

1 這是新的
- r+
1 f = open('test.txt','r+', encoding = 'utf-8') 2 f.write('這是r+') #寫入后指針跑到了新寫入內容的末尾 3 f.seek(0) 4 print(f.read()) #從開頭開始替換

1 這是r+rld 2 這是新的
2 文件讀
2.1 讀文件方法
- f.readline():讀文件的一行,文件指針移動到下一行
- f.readlines():讀從文件指針當前位置至末尾的所有行,文件指針移動到末尾。取文件里面所有內容,返回的是一個list,每一行的內容放到一個list
- f.read():讀從文件指針當前位置至末尾的所有內容,文件指針移動到末尾。讀取文件里面所有的內容,字符串
- for line in f: 直接循環文件對象,每次循環的line是文件的當前行內容,進入下一循環,則循環文件的下一行的內容
1 f = open('file.txt','r',encoding='utf-8') # 默認是當前路徑 2 print('1=====',f.readline()) #讀取文件一行的數據 3 print('2=====',f.readline()) #讀取文件第二行的數據,即接下來一行 4 print('3=====',f.readlines()) #讀取文件所有的數據,返回一個列表(從指針開始) 5 print('4=====',f.read()) # 獲取文件里的所有內容(從指針開始)
2.2 日志分析
1 #寫腳本每隔一分鍾讀日志文件,一分鍾訪問超200,禁止訪問 2 3 #1讀取文件內容,獲取ip 4 #2把每個ip地址存起來 . 5 #3判斷ip訪問的次數是否超過200 6 #4加入黑名單 print 7 8 import time 9 10 point = 0#初始位置 11 12 while True: 13 14 f = open('access.log','r', encoding = 'utf-8') 15 IP = {} 16 17 f.seek(point) 18 19 for line in f: #一行一行讀 20 str = line.split()[0] #split():通過指定分隔符對字符串進行切片,默認為所有的空字符,包括空格、換行(\n)、制表符(\t)等。 21 count = 0 22 if str in IP: 23 IP[str] += 1 24 else: 25 IP[str] = 1 26 27 point = f.tell() 28 29 f.close() 30 31 for k, v in IP.items(): 32 if v > 200: 33 print(k)
3 文件寫
3.1 寫文件方法
- f.writelines(listname):寫一個list。類似於 for i in list: f.write(i)。所以,雖然writelines()可以寫入string及list,但是字符串最好用write(),list最好用writelines()。自動循環,將list每一個元素追加寫到文件中,如果想加換行符,可以將換行符放在list表里
- f.write(str):寫一個字符串。不能自動循環,參數可自行加換行符,如 f.write('\n'+name)
- flush(): write后再調用flush,會將緩沖區里的內容立即寫到磁盤上。寫文件機制:cpu->內存->磁盤(為了提高效率,內存有緩沖區,當緩沖區滿了,再將緩沖區的內容寫到磁盤上)。
4 修改文件
4.1 方法一 不常用
1 # 文件修改的方法: 2 # 1、簡單粗暴直接(適用於數據量少的情況) 3 # 1)讀出來文件所有內容,保存為一個變量 4 # 2)對字符串變量進行處理 5 # 3)除舊存新 6 with open('a.data','a+',encoding='utf-8') as f: 7 f.seek(0) 8 data = f.read() #獲取原來的內容 9 print('修改前:%s'%data) 10 new_data = data.replace('你','You') 11 print('修改后:%s'%new_data) #修改內容 12 f.seek(0) 13 f.truncate() # 清空文件內容,需要將文件指針移到頭部再清空 14 f.write(new_data) #將修改后的內容存入文件 15 f.flush()

1 修改前:你好, 2 地球! 3 修改后:You好, 4 地球!
4.2 方法二 常用★
1 # 高效修改(一行一行修改) 2 # 1)循環取每一行,去除前面的空格 3 # 2)去除空行 4 # 3)你替換成you 5 # 4) 寫到新文件里 6 # 5)把原來文件刪除,把新文件的名字改成原文件的名字 7 import os 8 with open('a.data','r',encoding='utf-8') as f1, open('a2.data','w',encoding='utf-8') as f2: 9 for line in f1: # 1)循環取每一行,去除前面的空格 10 line = line.lstrip() # 1)去除前面的空格 11 if line: # 2)去除空行 12 print('修改前:%s'%line) 13 line = line.replace('You','你們') # 3)You替換成你們 14 print('修改后:%s'%line) 15 f2.write(line) # 4) 寫到新文件里 16 os.remove('a.data'); # 5)把原來文件刪除 17 os.rename('a2.data','a.data') # 5)把新文件的名字改成原文件的名字

1 修改前:You好, 2 3 修改后:你們好, 4 5 修改前:地球! 6 修改后:地球!
- os.remove('a.data'); #刪除文件
- os.rename('a2.data','a.data') #修改文件名
5 JSON處理
5.1 json.load(file)
自動讀取文件中的json,轉換成字典

{ "xiaohei": "7891", "海龍": "111", "tanailing": "11111", "xiaojun": "123456" }
1 import json 2 f = open('stus.json',encoding='utf-8') 3 user_dic = json.load(f) 4 print(user_dic)

{'xiaohei': '7891', '海龍': '111', 'tanailing': '11111', 'xiaojun': '123456'}
5.2 json.dump(dic, file, indent=4, ensure_ascii=False)
把字典轉成json串,並自動寫入文件中。
dump參數是(字典,文件句柄,indent)。indent用於縮進美化json串的。
ensure_ascii=False用於寫文件時有unicode時用,正常顯示出中文來。
1 import json 2 stus = {'xiaojun':'123456','xiaohei':'7891','tanailing':'11111' 3 ,'海龍':'111'} 4 f = open('stus2.json','w',encoding='utf-8') 5 json.dump(stus,f,indent=4,ensure_ascii=False)

生成文件'stus2.json', 文件內容是由字典生成的json
5.3 json.loads(str)
把json串(字符串)轉成字典。loads參數是字符串
1 import json 2 3 s=''' 4 { 5 "error_code": 0, 6 "stu_info": [ 7 { 8 "id": 309, 9 "name": "小白", 10 "sex": "男", 11 "age": 28, 12 "addr": "河南省濟源市北海大道32號", 13 "grade": "天蠍座", 14 "phone": "18512572946", 15 "gold": 100 16 }, 17 { 18 "id": 310, 19 "name": "小白", 20 "sex": "男", 21 "age": 28, 22 "addr": "河南省濟源市北海大道32號", 23 "grade": "天蠍座", 24 "phone": "18516572946", 25 "gold": 100 26 } 27 ] 28 } 29 ''' 30 31 res = json.loads(s) #json串(字符串),轉成字典 32 print(res)

{'error_code': 0, 'stu_info': [{'id': 309, 'name': '小白', 'sex': '男', 'age': 28, 'addr': '河南省濟源市北海大道32號', 'grade': '天蠍座', 'phone': '18512572946', 'gold': 100}, {'id': 310, 'name': '小白', 'sex': '男', 'age': 28, 'addr': '河南省濟源市北海大道32號', 'grade': '天蠍座', 'phone': '18516572946', 'gold': 100}]}
5.4 json.dumps(dic,ensure_ascii=False)
把字典轉成json串(字符串),loads參數是字典,需要手動write
1 import json 2 stus = {'xiaojun':'123456','xiaohei':'7891','tanailing':'11111','海龍':'111'} 3 res2 = json.dumps(stus,indent=8,ensure_ascii=False) 4 print(res2)

{ "xiaojun": "123456", "xiaohei": "7891", "tanailing": "11111", "海龍": "111" }
參數說明:
- 輸出中文需要指定ensure_ascii=False,如果使用默認配置, 輸出的會是‘ASCII字符
- indent參數根據數據格式縮進顯示,讀起來更加清晰 (數值代表縮進的位數)