文件處理

1.文件操做

1.1介紹

計算機系統分爲:計算機硬件,操做系統,應用程序三部分。python

咱們用python或其餘語言編寫的應用程序若想要把數據永久保存下來,必需要保存於硬盤中,這就涉及到應用程序要操做硬件,衆所周知,應用程序是沒法直接操做硬件的,這就用到了操做系統。操做系統把複雜的硬件操做封裝成簡單的接口給用戶/應用程序使用,其中文件就是操做系統提供給應用程序來操做硬盤虛擬概念,用戶或應用程序經過操做文件,能夠將本身的數據永久保存下來。linux

有了文件的概念,咱們無需再去考慮操做硬盤的細節,只須要關注操做文件的流程:vim

#1. 打開文件,獲得文件句柄並賦值給一個變量
#2. 經過句柄對文件進行操做
#3. 關閉文件

1.2在python中

#1. 打開文件,獲得文件句柄並賦值給一個變量
f=open('a.txt','r',encoding='utf-8') #默認打開模式就爲r

#2. 經過句柄對文件進行操做
data=f.read()

#3. 關閉文件
f.close() #回收操做系統的資源

1.3f=open('a.txt','r')的過程分析

#一、由應用程序向操做系統發起系統調用open(...)

#二、操做系統打開該文件,並返回一個文件句柄給應用程序

#三、應用程序將文件句柄賦值給變量f

1.4強調

#強調第一點:
打開一個文件包含兩部分資源:操做系統級打開的文件+應用程序的變量。在操做完畢一個文件時,必須把與該文件的這兩部分資源一個不落地回收,回收方法爲:
一、f.close() #回收操做系統級打開的文件
二、del f #回收應用程序級的變量

其中del f必定要發生在f.close()以後,不然就會致使操做系統打開的文件尚未關閉,白白佔用資源,
而python自動的垃圾回收機制決定了咱們無需考慮del f,這就要求咱們,在操做完畢文件後,必定要記住f.close()

雖然我這麼說,可是仍是會忘記f.close(),咱們推薦傻瓜式操做方式:使用with關鍵字來幫咱們管理上下文
with open('a.txt','w') as f:
    pass
 
with open('a.txt','r') as read_f,open('b.txt','w') as write_f:
    data=read_f.read()
    write_f.write(data)
f=open(...)是由操做系統打開文件,那麼若是咱們沒有爲open指定編碼,那麼打開文件的默認編碼很明顯是操做系統說了算了,操做系統會用本身的默認編碼去打開文件,
在windows下是gbk,在linux下是utf-8。 這就用到了上節課講的字符編碼的知識:若要保證不亂碼,文件以什麼方式存的,就要以什麼方式打開。 f=open('a.txt','r',encoding='utf-8')

1.5python2中的file與open

#首先在python3中操做文件只有一種選擇,那就是open()

#而在python2中則有兩種方式:file()與open()
二者都可以打開文件,對文件進行操做,也具備類似的用法和參數,可是,這兩種文件打開方式有本質的區別,file爲文件類,用file()來打開文件,
至關於這是在構造文件類,而用open()打開文件,是用python的內建函數來操做,咱們通常使用open()打開文件進行操做,而用file當作一個類型,好比type(f) is file

2.打開文件的方式

文件句柄 = open('文件路徑', '模式')

模式能夠是如下方式以及他們之間的組合:windows

Character Meaning
‘r' open for reading (default)
‘w' open for writing, truncating the file first
‘a' open for writing, appending to the end of the file if it exists
‘b' binary mode
‘t' text mode (default)
‘+' open a disk file for updating (reading and writing)
‘U' universal newline mode (for backwards compatibility; should not be used in new code)

 

 

 

 

 

 

#1. 打開文件的模式有(默認爲文本模式):
r ,只讀模式【默認模式,文件必須存在,不存在則拋出異常】
w,只寫模式【不可讀;不存在則建立;存在則清空內容】
a, 之追加寫模式【不可讀;不存在則建立;存在則只追加內容】

#2. 對於非文本文件,咱們只能使用b模式,"b"表示以字節的方式操做(而全部文件也都是以字節的形式存儲的,使用這種模式無需考慮文本文件的字符編碼、圖片文件的jgp格式、視頻文件的avi格式)
rb 
wb
ab
注:以b方式打開時,讀取到的內容是字節類型,寫入時也須要提供字節類型,不能指定編碼

#3. 瞭解部分
"+" 表示能夠同時讀寫某個文件
r+, 讀寫【可讀,可寫】
w+,寫讀【可讀,可寫】
a+, 寫讀【可讀,可寫】


x, 只寫模式【不可讀;不存在則建立,存在則報錯】
x+ ,寫讀【可讀,可寫】
xb

  

3.操做文件的方法

#掌握
f.read() #讀取全部內容,光標移動到文件末尾
f.readline() #讀取一行內容,光標移動到第二行首部
f.readlines() #讀取每一行內容,存放於列表中

f.write('1111\n222\n') #針對文本模式的寫,須要本身寫換行符
f.write('1111\n222\n'.encode('utf-8')) #針對b模式的寫,須要本身寫換行符
f.writelines(['333\n','444\n']) #文件模式
f.writelines([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')]) #b模式

#瞭解
f.readable() #文件是否可讀
f.writable() #文件是否可讀
f.closed #文件是否關閉
f.encoding #若是文件打開模式爲b,則沒有該屬性
f.flush() #馬上將文件內容從內存刷到硬盤
f.name

練習,利用b模式,編寫一個cp工具,要求以下:app

  1. 既能夠拷貝文本又能夠拷貝視頻,圖片等文件編輯器

  2. 用戶一旦參數錯誤,打印命令的正確使用方法,如usage: cp source_file target_file函數

  提示:能夠用import sys,而後用sys.argv獲取腳本後面跟的參數工具

import sys
if len(sys.argv) != 3:
    print('usage: cp source_file target_file')
    sys.exit()

source_file,target_file=sys.argv[1],sys.argv[2]
with open(source_file,'rb') as read_f,open(target_file,'wb') as write_f:
    for line in read_f:
        write_f.write(line)
複製代碼

4.測試

4.文件內光標移動

一: read(3):

  1. 文件打開方式爲文本模式時,表明讀取3個字符

  2. 文件打開方式爲b模式時,表明讀取3個字節

二: 其他的文件內光標移動都是以字節爲單位如seek,tell,truncate

注意:

  1. seek有三種移動方式0,1,2,其中1和2必須在b模式下進行,但不管哪一種模式,都是以bytes爲單位移動的

  2. truncate是截斷文件,因此文件的打開方式必須可寫,可是不能用w或w+等方式打開,由於那樣直接清空文件了,因此truncate要在r+或a或a+等模式下測試效果
import time
with open('test.txt','rb') as f:
    f.seek(0,2)
    while True:
        line=f.readline()
        if line:
            print(line.decode('utf-8'))
        else:
            time.sleep(0.2)

5文件的修改

文件的數據是存放於硬盤上的,於是只存在覆蓋、不存在修改這麼一說,咱們平時看到的修改文件,都是模擬出來的效果,具體的說有兩種實現方式:編碼

方式一:將硬盤存放的該文件的內容所有加載到內存,在內存中是能夠修改的,修改完畢後,再由內存覆蓋到硬盤(word,vim,nodpad++等編輯器)

import os

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    data=read_f.read() #所有讀入內存,若是文件很大,會很卡
    data=data.replace('alex','SB') #在內存中完成修改

    write_f.write(data) #一次性寫入新文件

os.remove('a.txt')
os.rename('.a.txt.swap','a.txt') 
複製代碼

方式二:將硬盤存放的該文件的內容一行一行地讀入內存,修改完畢就寫入新文件,最後用新文件覆蓋源文件

import os

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:
    for line in read_f:
        line=line.replace('alex','SB')
        write_f.write(line)

os.remove('a.txt')
os.rename('.a.txt.swap','a.txt') 
複製代碼

練習題:

1. 文件a.txt內容:每一行內容分別爲商品名字,價錢,個數,求出本次購物花費的總錢數
apple 10 3
tesla 100000 1
mac 3000 2
lenovo 30000 3
chicken 10 3

2. 修改文件內容,把文件中的xiaoqiao都替換成qiaolu
相關文章
相關標籤/搜索