當我們讀取文件內容時,並不能重復的讀取,比如一個blogCblog.txt文件里有blogCblog內容,用兩個read()方法讀取blogCblog.txt的內容,會發現,第一個返回文件內容,第二個返回‘’。並不能重復讀取,如果我想重復讀取呢?怎么解決。
其實這跟文件指針有關,當我們對文件操作時,文件內部會有一個文件指針來定位當前位置,如圖:
當open時文件指針是在初始位置1,當讀取4個字節內容是文件指針位置就在4,再write時,文件指針從4移到8,所以,只要控制了文件指針,就能重復的讀取了!
操作文件指針可以通過seek方法:
seek(offset, whence):移動文件指針
offset:偏移量,可為負數
whence:偏移相對位置
偏移相對位置為os模塊當中的SEEK_SET、SEEK_CUR、SEEK_END:
os.SEEK_SET:表示文件的相對起始位置
os.SEEK_CUR:表示文件的相對當前位置
os.SEEK_END:表示文件的相對結束位置
來看下實例代碼(一個blogCblog.txt文件里有blogCblog內容):
1 f = open('blogCblog.txt') #首先先創建一個文件對象 2 print f.read(3) #用read()方法讀取並打印 3 print f.tell() #打印出文件指針的位置 4 f.close() #關閉文件 5 6 #打印結果:blo 7 # 3
上面可以看到用read(3)讀取3個字節的內容,而tell()方法返回文件指針的位置。下面來操作文件指針:
1 import os #導入os模塊 2 f = open('blogCblog.txt') #首先先創建一個文件對象,打開方式為w 3 print f.read(3) #用read()方法讀取並打印 4 print f.tell() #打印出文件指針的位置 5 f.seek(0, os.SEEK_SET) #用seek()方法操作文件指針(把文件指針移到文件起始位置並移動0) 6 print f.read(3) #用read()方法再次讀取並打印 7 print f.tell() #打印出文件指針的位置 8 f.close() #關閉文件 9 10 #打印結果:blo 11 # 3 12 # blo 13 # 3
上面的代碼就重復讀取了,如果把第五行注釋掉,那么第6、7行代碼打印的結果為gCb和6,這是因為文件指針在第3,當再次讀取時就在當前的文件指針向后移,這也就是為什么readline()會記住讀取位置的原因了。而第5行代碼的作用就是把文件指針移到初始位置!就實現了重復讀取。
當你移到指針時,偏移量大於字符串長度時就會報IOError,需要注意!
項目實戰
# 生成Excel導出 def basic_export_excel(file_addr=None, data=None, data_key=None, header=None, sheet_name=None): fp = io.BytesIO() book = Workbook(file_addr if file_addr is not None else fp) sheet = book.add_worksheet(sheet_name) for idx, head in enumerate(header): sheet.write(0, idx, head) for row_number, row_data in enumerate(data): for col, key in enumerate(data_key): insert_val = row_data[key] if isinstance(insert_val, datetime): insert_val = insert_val.strftime('%Y-%m-%d %H:%M:%S') elif isinstance(insert_val, date): insert_val = insert_val.strftime('%Y-%m-%d') elif isinstance(insert_val, list): insert_val = str(insert_val) sheet.write(row_number + 1, col, insert_val) book.close() fp.seek(0) return fp # 開始調用 fp = basic_export_excel(data=hardware_data, data_key=fields, header=field_des) # 給前端發送文件 return send_file(filename_or_fp=fp, attachment_filename=sheet_title, as_attachment=True)