1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 #Author:sking 4 """ 5 test_file.txt 6 文件內容如下: 7 打印字符串第一個字符 8 9 打印字符串第二個字符 10 """ 11 #打開文件test_file.txt 12 f = open('test_file.txt', 'r+') #f是文件的文件句柄,它是在內存中的,是內存中的一個對象 13 data = f.read() 14 print(data) 15 """ 16 data結果: 17 打印字符串第一個字符 18 19 打印字符串第二個字符 20 """ 21 data2 = f.read() #再讀一次文件 22 print("data2=", data2) #data2= 23 # 此時的結果是data2= ,也就是此時讀取的data2為空,為什么? 24 # 因為第一次data讀的時候文件光標是從頭開始一直讀到最后的,再次讀的時候, 25 # 是從此時光標所在的位置(此時光標在最后面)開始讀取,因為光標已經在最后了, 26 # 后面已經沒有任何內容了,當然data2就讀不出來數據了 27 # 可以用seek重新定位光標的位置 28 f.seek(0) #將光標定位到文件的開始位置 29 data3 = f.read() 30 print(data3) 31 """ 32 data3結果: 33 打印字符串第一個字符 34 35 打印字符串第二個字符 36 """ 37 #寫文件write 38 #f = open('test_file.txt', 'w') #如果是'w'寫的模式的時候,系統會自動創建一個這個名字的文件, 39 # 如果該目錄下有這個名字的文件,系統會直接覆蓋掉原來的文件,原來的文件及內容就不存在了,所以這點一定要注意。 40 #f.write('\n\n寫入字符串第三個字符') 41 f.seek(0) #seekable()判斷文件內容是否可以進行seek操作,因為有些文件是不可以進行seek的 42 data4 = f.read() 43 print(data4) 44 f.close() 45 """ 46 打印字符串第一個字符 47 48 打印字符串第二個字符 49 50 寫入字符串第三個字符 51 """ 52 #向文件追加內容 53 f = open('test_file.txt', 'a') #'a'是append 追加,但是不能讀取文件 54 f.write('\n\nhaha') 55 print(f.readable()) #False 判斷文件是否可讀 56 f.close() 57 #讀取一行內容 58 f = open('test_file.txt', 'r') 59 data = f.readline() 60 print(data) # 打印字符串第一個字符 61 #讀取多行 62 data2 = f.readlines() 63 print(data2) 64 65 66 #讀取到第3行 67 for index, line in enumerate(f.readlines()): #僅適合讀取小文件 68 print(line.strip()) 69 if index == 2: 70 break; 71 f.close() 72 #讀取大文件(推薦使用) 73 f = open('test_file.txt', 'r') 74 for line in f: #這樣寫的效果就是逐行讀取文件中的內容,並且內存中始終僅保存讀取的這一行內容 此時的f是一個迭代器 75 print(line) 76 f.close() 77 #查看文件游標所在的位置 78 f = open('test_file.txt', 'r') 79 print(f.tell()) #0 80 print(f.read(5)) 81 print(f.tell()) #10 因為一個漢字占2個字節,所以這里顯示的是10 82 f.close() 83 f2 = open('test_file2.txt', 'r') 84 print(f2.tell()) #0 85 print(f2.read(5)) 86 print(f2.tell()) #5 因為一個英文占1個字節,所以這里顯示的是5 87 f2.close() 88 89 90 f = open('test_file.txt', 'r+') 91 print(f.encoding) #cp936 #查看文件編碼 92 print(f.name) # test_file.txt 查看文件名 93 94 #實時存儲數據 95 #f.write("sdfadf") #因為代碼執行的過程中並不是出現依據寫到硬盤的代碼就立馬開始向硬盤存儲。 96 #系統有一個閥門限制,系統會在內存中開辟一塊用來臨時存儲的區域,當臨時存儲區域的數據達到一定值時,才會從內存存到硬盤上。 97 #所以並不是執行一行寫的代碼后,硬盤就一定已經保存了該結果,很可能該結果還沒有被保存。 98 f.flush() 99 print(f.flush()) #None 100 101 f.close() 102 103 #截斷字符truncate 104 f = open('test_file.txt', 'r+') 105 f.truncate(10) #打印字符串 從文件頭開始截取10個字節(一個漢字是2個字節) 106 f.truncate() #如果什么都不寫,就是截取0個字節也就相當於清空文件內容 107 f.close() 108 109 #寫二進制文件內容 110 f = open('test_file.txt', 'wb') 111 f.write('hello'.encode(encoding='utf-8')) 112 f.close() 113 114 #演示進度條 115 import sys 116 import time 117 for i in range(31): 118 sys.stdout.write('#') 119 sys.stdout.flush() 120 time.sleep(0.3) 121 122 123 """ 124 一、文件操作 125 1.文件處理的流程 126 127 128 1)打開文件,得到文件句柄並賦值給一個變量 129 130 2)通過句柄對文件進行操作 131 132 3)關閉文件 133 134 例如: 135 136 f = open('chenli.txt') #打開文件 137 first_line = f.readline() 138 print('first line:',first_line) #讀一行 139 data = f.read()# 讀取剩下的所有內容,文件大時不要用 140 print(data) #打印讀取內容 141 f.close() #關閉文件 142 143 144 2.文件操作基本用法 145 1)基本用法: 146 147 file_object = open(file_name, access_mode = ‘r’, buffering = -1) 148 149 open函數有很多的參數,常用的是file_name,mode和encoding 150 151 file_name:打開的文件名,若非當前路徑,需指出具體路徑 152 access_mode文件打開模式 153 buffering的可取值有0,1,>1三個,0代表buffer關閉(只適用於二進制模式),1代表line buffer(只適用於文本模式),>1表示初始化的buffer大小; 154 encoding表示的是返回的數據采用何種編碼,一般采用utf8或者gbk; 155 156 157 158 159 2)文件打開模式 160 161 r ,只讀模式【默認模式,文件必須存在,不存在則拋出異常】 162 w,只寫模式【不可讀;不存在則創建;存在則清空內容】 163 x, 只寫模式【不可讀;不存在則創建,存在則報錯】 164 a, 追加模式【不可讀文件,不存在則創建;存在則只追加內容】,文件指針自動移到文件尾。 165 "+" 表示可以同時讀寫某個文件 166 167 r+, 讀寫【可讀,可寫】 168 w+,寫讀【可讀,可寫】,消除文件內容,然后以讀寫方式打開文件。 169 x+ ,寫讀【可讀,可寫】 170 a+, 寫讀【可讀,可寫】,以讀寫方式打開文件,並把文件指針移到文件尾。 171 "b"表示以字節的方式操作,以二進制模式打開文件,而不是以文本模式。 172 173 174 175 rb 或 r+b 176 wb 或 w+b 177 xb 或 w+b 178 ab 或 a+b 179 注:以b方式打開時,讀取到的內容是字節類型,寫入時也需要提供字節類型,不能指定編碼 180 181 182 183 3)以讀r的方式打開文件 184 185 186 187 #!/usr/bin/env python 188 # -*- coding:utf-8 -*- 189 f=open('1.txt',encoding='utf-8',mode='r') 190 print(f) 191 data1=f.read() 192 print(data1) 193 194 195 1.txt 196 197 55542342 198 123 199 輸出: 200 201 <_io.TextIOWrapper name='1.txt' mode='r' encoding='utf-8'> 202 55542342 203 123 204 205 206 補充: 207 208 復制代碼 209 1)python中有三個方法來處理文件內容的讀取: 210 read() #一次讀取全部的文件內容。返回字符串 211 212 readline() #每次讀取文件的一行。 213 214 readlines() #讀取文件的所有行,返回一個字符串列表。 215 216 2)print(f.readable()) #判斷文件是否是r模式打開的 217 218 3)print(f.closed) #判斷文件是否是關閉狀態 219 220 4)python中在文本文件內容移動的操作 221 file.seek(offset,whence=0) #從文件中給移動指針,從whence(0起始,1當前,2末尾)偏移offset個字節,正往結束方向移動,負往開始方向移動 222 file.tell() #返回當前文件中的位置。獲得文件指針位置 223 224 5) file.truncate(size=file.tell()) #截取文件到最大size個字節,默認為當前文件位置 225 復制代碼 226 4)以w方式寫入文件 227 228 復制代碼 229 f=open('a.txt','w',encoding='utf-8') 230 # f=open('b.txt','r',encoding='utf-8') #以讀的方式打開文件,文件不存在則報錯 231 f=open('b.txt','w',encoding='utf-8') 232 # print(f.writable()) 233 234 f.write('111111\n22222222') 235 f.seek(0) 236 f.write('\n333333\n444444') 237 238 f.writelines(['\n55555\n','6666\n','77777\n']) 239 f.close() 240 復制代碼 241 a.txt 為空 242 243 b.txt 244 245 333333 246 444444 247 55555 248 6666 249 77777 250 251 252 補充: 253 254 file.write(str) #向文件中寫入字符串(文本或二進制) 255 file.writelines(seq) #寫入多行,向文件中寫入一個字符串列表,注意,要自己加入每行的換行符 256 file.flush() #刷新文件內部緩沖,直接把內部緩沖區的數據立刻寫入文件, 而不是被動的等待輸出緩沖區寫入. 257 258 259 5)文件修改 260 261 復制代碼 262 #!/usr/bin/env python 263 # -*- coding:utf-8 -*- 264 import os 265 read_f=open('b.txt','r') 266 write_f=open('.b.txt.swap','w') 267 for line in read_f.readlines(): 268 if line.startswith('1111'): 269 line='2222222222\n' 270 write_f.write(line) 271 read_f.close() 272 write_f.close() 273 os.remove('b.txt') 274 os.rename('.b.txt.swap','b.txt') 275 復制代碼 276 277 278 3.上下文管理with語句 279 當你做文件處理,你需要獲取一個文件句柄,從文件中讀取數據,然后關閉文件句柄。 280 281 正常情況下,代碼如下: 282 283 file = open("/tmp/foo.txt") 284 data = file.read() 285 file.close() 286 這里有兩個問題。一是可能忘記關閉文件句柄;二是文件讀取數據發生異常,沒有進行任何處理。 287 288 然而with可以很好的處理上下文環境產生的異常。下面是with版本的代碼: 289 290 with open("/tmp /foo.txt") as file: 291 data = file.read() 292 with的基本思想是with所求值的對象必須有一個__enter__()方法,一個__exit__()方法。緊跟with后面的語句被求值后,返回對象的__enter__()方法被調用,這個方法的返回值將被賦值給as后面的變量。當with后面的代碼塊全部被執行完之后,將調用前面返回對象的__exit__()方法。 293 294 295 296 補充: 297 298 模擬 tail -f access.log 299 300 復制代碼 301 #!/usr/bin/env python 302 # -*- coding:utf-8 -*- 303 304 # tail -f access.log 305 import time 306 with open('access.log','r',encoding='utf-8') as f: 307 f.seek(0,2) 308 while True: 309 line=f.readline().strip() 310 if line: 311 print('新增一行日志',line) 312 time.sleep(0.5) 313 復制代碼 314 315 316 """ 317 """ 318 read(),readline(),readlines()的區別 319 320 假設a.txt的內容如下所示: 321 123 322 Hello 323 Welcome 324 What is the fuck... 325 326 一、read([size])方法 327 328 read([size])方法從文件當前位置起讀取size個字節,若無參數size, 329 則表示讀取至文件結束為止,它范圍為字符串對象 330 f = open("a.txt") 331 lines = f.read() 332 print(lines) 333 print(type(lines)) 334 f.close() 335 336 輸出結果: 337 Hello 338 Welcome 339 What is the fuck... 340 <type 'str'> #字符串類型 341 342 二、readline()方法 343 344 從字面意思可以看出,該方法每次讀出一行內容,所以,讀取時占用內存小,比較適合大文件,該方法返回一個字符串對象。 345 346 f = open("a.txt") 347 line = f.readline() 348 print(type(line)) 349 while line: 350 print line, 351 line = f.readline() 352 f.close() 353 354 輸出結果: 355 356 <type 'str'> 357 Hello 358 Welcome 359 What is the fuck... 360 361 三、readlines()方法讀取整個文件所有行,保存在一個列表(list)變量中,每行作為一個元素,但讀取大文件會比較占內存。 362 363 f = open("a.txt") 364 lines = f.readlines() 365 print(type(lines)) 366 for line in lines: 367 print (line) 368 f.close() 369 370 輸出結果: 371 <type 'list'> 372 Hello 373 Welcome 374 What is the fuck... 375 376 四、linecache模塊 377 378 當然,有特殊需求還可以用linecache模塊,比如你要輸出某個文件的第n行: 379 380 # 輸出第2行 381 text = linecache.getline(‘a.txt',2) 382 print text, 383 384 對於大文件效率還可以。 385 """