記錄個人 python 學習歷程-Day08 文件的操做

文件操做的初識

  • 用 python 代碼對文件進行各類操做。python

    基本構成:vim

    • 文件路徑:path
    • 打開方式:讀、寫、追加、讀寫、寫讀……
    • 編碼方式:utf-8 / gbk / gb2312……
    f = open('文件路徑或者相對路',encoding='編碼方式',mode='模式') # 格式構成
    cotent = f.read()
    print(content)
    f.close()
  • 代碼解釋:編輯器

    • open:函數

      ​ 內置函數,open 底層調用的是操做系統的接口。測試

    • f:編碼

      ​ 變量,約定俗成的變量名有(f1,fh,file_handler,f_h),這個變量還有一個名字,叫文件句柄。對亠件進行的任何操做,都得經過文件句柄加'.'的方式。操作系統

    • encoding:指針

      ​ 能夠不寫,若是不寫,默認的編碼本就是系統默認的編碼。code

      ​ Windows: gkb視頻

      ​ Linux: utf-8

      ​ MacOS: utf-8

    • mode:

      ​ 就是定義你的操做方式:r 爲讀模式。

    • f.read():

      ​ 你想操做文件,好比讀文件,給文件寫內容,等等,都必須經過文件句柄進行操做。

    • f.colse():

      ​ 關閉文件。(必須關閉,不然會常駐內存。)

  • 文件操做的三個步驟:

    • 打開文件。

    • 對文件句柄進行相應的操做。

    • 關閉文件。

      # 打開文件,獲得文件句柄並賦值給一個變量
      f = open('文件.txt', 'r', encoding='utf-8')   # 默認打開模式就爲 r
      
      # 經過句柄對文件進行操做
      date = f.read()
      
      # 關閉文件
      f.close()
  • 報錯的緣由:

    • UnicodeDecodeError:文件存儲時與文件打開時編碼本不一致。

    • 路徑分隔符產生的問題:

      解決方法:在路徑前加個 r
      r'C:\Users\Desktop\文件.txt'

文件操做的:讀

​ 文件操做的讀,有四種模式(r、rb、r+、r+b),r+ 和 r+b 不經常使用, rb 操做的是非文本的文件,好比:圖片、視頻、音頻。每種模式有五種方法(read()、read(n)、readline()、readlines()、for)。

  • r 模式

    ​ 以只讀方式打開文件,文件的指針將會放在文件的開頭。是文件操做最經常使用的模式,也是默認模式,若是一個文件不設置mode,那麼默認使用r模式操做文件。

    舉例:

    f = open('文件.txt', mode='r', encoding='utf-8')
    msg = f.read()
    f.close()
    print(msg)
    • read() 一次性所有讀取

      read() 將文件中的內容所有讀取出來; 弊端:若是文件很大就會很是的佔用內存,容易致使內存崩潰。

      f = open('測試', mode='r', encoding='utf-8')
      msg = f.read()
      f.close()
      print(msg)
      
      # 輸出結果:
      這是一行測試
      A:這是第二行
      B:這是第三行
      C:這是第幾行
      D:這是我也不知道第幾行
      就這麼地吧.
    • read(n) 指定讀取到什麼位置

      在 r 模式下,n 按照字符讀取

      f = open('測試', mode='r', encoding='utf-8')
      msg = f.read(4)
      f.close()
      print(msg)
      
      # 輸出結果:
      這是一行
    • readline() 按行讀取

      readline() 每次只讀取一行,注意: readline() 讀取出來的數據在後面都有一個\n,解決這個問題只須要在咱們讀取出來的文件後邊加一個strip()就OK了

      f = open('測試', mode='r', encoding='utf-8')
      msg1 = f.readline()
      msg2 = f.readline().strip()
      msg3 = f.readline()
      msg4 = f.readline()
      f.close()
      print(msg1)
      print(msg2)
      print(msg3)
      print(msg4)
      
      # 輸出結果:
      這是一行測試
      
      A:這是第二行
      B:這是第三行
      
      C:這是第幾行
    • readlines() 返回一個列表

      readlines() 返回一個列表,列表裏面每一個元素是原文件的每一行,若是文件很大,佔內存,容易崩盤。

      f = open('測試', mode='r', encoding='utf-8')
      print(f.readlines())    # 還能夠這麼寫的,哈哈
      f.close()
      
      # 輸出結果:
      ['這是一行測試\n', 'A:這是第二行\n', 'B:這是第三行\n', 'C:這是第幾行\n', 'D:這是我也不知道第幾行\n', '就這麼地吧.']

    上面這四種都不太好,若是文件超大,內容超多,他們就很容易將內存撐爆,因此,咱們還有第五種方法。

    • for 循環

      能夠經過for循環去讀取,文件句柄是一個迭代器,他的特色就是每次循環只在內存中佔一行的數據,很是節省內存。

      f = open('測試', mode='r', encoding='utf-8')
      for line in f:
          print(line)     # 去掉 \n 能夠這樣寫: print(line.strip())  
      # 這種方式就是在一行一行的進行讀取,它就執行了下邊的功能
      
      '''
      print(f.readline())
      print(f.readline())
      print(f.readline())
      .......
      '''
      # 輸出結果:
      這是一行測試
      
      A:這是第二行
      
      B:這是第三行
      
      C:這是第幾行
      
      D:這是我也不知道第幾行
      
      就這麼地吧.

    特別注意: 讀完的文件必定必需要關閉

  • rb 模式

    rb模式:以二進制格式打開一個文件用於只讀。文件指針將會放在文件的開頭。記住下面講的也是同樣,帶b的都是以二進制的格式操做文件,他們主要是操做非文字文件:圖片,音頻,視頻等,而且若是你要是帶有b的模式操做文件,那麼不用聲明編碼方式。

    f1 = open('圖片.jpeg', mode='rb')
    tu = f1.read()
    f1.close()
    print(tu)
    
    # 輸出結果:
    b'\xff\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00H\x00H\x00\x00\xff\xe1\x00\xb0Exif\x............後面還有.老長老長了..此處省略了.

    rb模式也有read read(n) readline(),readlines() for循環這幾種方法,這裏就不一一演示了。

文件操做的:寫

​ 文件操做的寫,有四種模式(w、wb、w+、w+b),w+ 和 w+b 不經常使用, wb 操做的是非文本的文件,好比:圖片、視頻、音頻。操做方法是:write('要寫入的內容')

  • w 模式

    若是文件不存在,用 w 模式操做文件,它會先建立文件,而後寫入內容。

    f = open('這是一個新建立的文件', encoding='utf-8', mode='w')
    f.write('果真是一個新建立的文件')
    f.close()

    若是文件存在,利用w模式操做文件,先清空原文件內容,在寫入新內容。

    f = open('這是一個新建立的文件', encoding='utf-8', mode='w')
    f.write('這是清空後從新寫入的內容')
    f.close()
  • wb 模式

    wb模式:以二進制格式打開一個文件只用於寫入。若是該文件已存在則打開文件,並從開頭開始編輯,即原有內容會被刪除。若是該文件不存在,建立新文件。通常用於非文本文件如:圖片,音頻,視頻等。

    >>舉個例子 :

    我先以rb的模式將一個圖片的內容以bytes類型所有讀取出來,而後在以wb將所有讀取出來的數據寫入一個新文件,這樣我就完成了相似於一個圖片複製的流程。具體代碼以下:

    # 第一步:將原圖片經過 rb 模式讀取出來。
    f = open('圖片.jpeg', mode='rb')
    content = f.read()
    f.close()
    # 第二步:將讀取出來的數據經過 wb 模式寫入新文件。
    f1 = open('圖片1.jpeg', mode='wb')
    f1.write(content)
    f1.close()

文件操做的:追加

就是在文件中追加內容。這裏也有四種文件分類主要四種模式:a,ab,a+,a+b,咱們只講a

  • a 模式

    若是文件不存在,利用a模式操做文件,那麼它會先建立文件,而後寫入內容。

    f = open('追加文本', encoding='utf-8', mode='a')
    f.write('這個文件是沒有的,我是新建立的')
    f.close()

    若是文件存在,利用a模式操做文件,那麼它會在文件的最後面追加內容。

    f = open('追加文本', encoding='utf-8', mode='a')
    f.write('這是己存在的文件,我是新追加的內容')
    f.close()

文件操做的其它模式

​ 我們還有一種模式沒有講,就是那種帶+號的模式。什麼是帶+的模式呢?+就是加一個功能。好比剛纔講的r模式是隻讀模式,在這種模式下,文件句柄只能進行相似於read的這讀的操做,而不能進行write這種寫的操做。因此咱們想讓這個文件句柄既能夠進行讀的操做,又能夠進行寫的操做,那麼這個如何作呢?這就是接下來要說這樣的模式:r+ 讀寫模式,w+寫讀模式,a+寫讀模式,r+b 以bytes類型的讀寫模式.........
在這裏我們只講一種就是r+,其餘的大同小異,本身能夠練練就好了。

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

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

#3,‘+’模式(就是增長了一個功能)
r+,讀寫【可讀,可寫】
w+,寫讀【可寫,可讀】
a+,寫讀【可寫,可讀】

#4,以bytes類型操做的讀寫,寫讀,寫讀模式
r+b,讀寫【可讀,可寫】
w+b,寫讀【可寫,可讀】
a+b,寫讀【可寫,可讀】
  • r+ 模式 讀並追加 順序不能錯

    r+: 打開一個文件用於讀寫。文件指針默認將會放在文件的開頭。

    f = open('文件的讀寫.txt', encoding='utf-8', mode='r+')
    content = f.read()
    print(content)
    f.write('這是新寫入的內容')
    f.close()

      注意:若是你在讀寫模式下,先寫後讀,那麼文件就會出問題,由於默認光標是在文件的最開始,你要是先寫,則寫入的內容會講原內容覆蓋掉,直到覆蓋到你寫完的內容,而後在後面開始讀取。

小總結:

三個大方向:
​ 讀, 四種模式: r rb r+ r+b
​ 寫, 四種模式 : w,wb, w+,w+b
​ 追加 四種模式: a, ab, a+,a+b

相應的功能:
​ 對文件句柄的操做:read read(n) readline() readlines() write()

文件操做的其它功能

  • f.tell() 獲取光標的位置 單位是:字節

    f = open('測試', encoding='utf-8', mode='r')
    print(f.tell())
    content = f.read()
    print(f.tell())
    f.close()
    
    # 原文件內容
    這是一行測試
    A:這是第二行
    B:這是第三行
    C:這是第幾行
    D:這是我也不知道第幾行
    就這麼地吧.
    
    # 輸出結果:
    0   # 開始的位置
    122 # 結束的位置
  • f.seek() 調整光標的位置 (注意:移動單位是byte , 若是是utf-8的中文部分要是3的倍數)

    f = open('測試', encoding='utf-8', mode='r')
    f.seek(9)
    content = f.read()
    print(content)
    f.close()
    
    # 原文件內容
    這是一行測試
    A:這是第二行
    B:這是第三行
    C:這是第幾行
    D:這是我也不知道第幾行
    就這麼地吧.
    
    # 輸出結果:
    行測試
    A:這是第二行
    B:這是第三行
    C:這是第幾行
    D:這是我也不知道第幾行
    就這麼地吧.
  • f.flush() 強制刷新

    f = open('測試', encoding='utf-8', mode='w')
    f.write('fafdsfsfsadfsaf')
    f.flush()
    f.close()

打開文件的另外一種方式(經常使用的是這種)

  • with open() as ....

    # 優勢1:不用手動關閉文件句柄
    # 利用with上下文管理這種方式,它會自動關閉文件句柄。
    with open('測試', encoding='utf-8', mode='r') as f:
        print(f.read())
    
    # 優勢2:能夠加多個 open 操做
    # 一個with 語句能夠操做多個文件,產生多個文件句柄。
    with open('測試', encoding='utf-8', mode='r') as f,\
            open('測試', encoding='utf-8', mode='w') as f1:
        print(f.read())
        f1.write('kckckckckckckkck')

      這裏要注意一個問題,雖然使用with語句方式打開文件,不用你手動關閉文件句柄,比較省事兒,可是依靠其自動關閉文件句柄,是有一段時間的,這個時間不固定,因此這裏就會產生問題,若是你在with語句中經過r模式打開t1文件,那麼你在下面又以a模式打開t1文件,此時有可能你第二次打開t1文件時,第一次的文件句柄尚未關閉掉,可能就會出現錯誤,他的解決方式只能在你第二次打開此文件前,手動關閉上一個文件句柄。

文件的修改

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

  • 文件操做改的流程:
    1,以讀的模式打開原文件。
    2,以寫的模式建立一個新文件。
    3,將原文件的內容讀出來修改爲新內容,寫入新文件。
    4,將原文件刪除。
    5,將新文件重命名成原文件。

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

    import os   # 調用系統模塊
    with open('測試', encoding='utf-8') as f1,\
        open('測試.bak', encoding='utf-8',mode='w') as f2:
        old_content = f1.read() # 所有讀入內存,若是文件很大,會卡死
        new_content = old_content.replace('文', 'wen')   # 在內存中完成修改
        f2.write(new_content)   # 一次性寫入新文件
    os.remove('測試') # 刪除原文件
    os.rename('測試.bak', '測試')   # 將新建的文件重命名爲原文件
    
    # 原文件內容
    **文件操做改的流程:**
    1,以讀的模式打開原文件。
    2,以寫的模式建立一個新文件。
    3,將原文件的內容讀出來修改爲新內容,寫入新文件。
    4,將原文件刪除。
    5,將新文件重命名成原文件。
    # 修改後的內容
    **wen件操做改的流程:**
    1,以讀的模式打開原wen件。
    2,以寫的模式建立一個新wen件。
    3,將原wen件的內容讀出來修改爲新內容,寫入新wen件。
    4,將原wen件刪除。
    5,將新wen件重命名成原wen件。
  • 方式二:將硬盤存放的該文件的內容一行一行地讀入內存,修改完畢就寫入新文件,最後用新文件覆蓋源文件(這種是經常使用的)

    import os
    with open('測試', encoding='utf-8') as f1,\
        open('測試.bak', encoding='utf-8',mode='w') as f2:
        for line in f1: # 一行一行的改,佔內存少
            new_line = line.replace('wen', '文')
            f2.write(new_line)
    os.remove('測試')
    os.rename('測試.bak', '測試')
    
    # 原文件內容
    **wen件操做改的流程:**
    1,以讀的模式打開原wen件。
    2,以寫的模式建立一個新wen件。
    3,將原wen件的內容讀出來修改爲新內容,寫入新wen件。
    4,將原wen件刪除。
    5,將新wen件重命名成原wen件。
    
    # 修改後的內容
    **文件操做改的流程:**
    1,以讀的模式打開原文件。
    2,以寫的模式建立一個新文件。
    3,將原文件的內容讀出來修改爲新內容,寫入新文件。
    4,將原文件刪除。
    5,將新文件重命名成原文件。
相關文章
相關標籤/搜索