1. 程式人生 > >python 3 之檔案操作

python 3 之檔案操作

檔案操作
1.檔案處理的流程 
1)開啟檔案,得到檔案控制代碼並賦值給一個變數
2)通過控制代碼對檔案進行操作
3)關閉檔案
        能呼叫方法的一定是物件
        li=[1,2,3]
        li.append('2')
        'asc'.capitalize()
    例如:
        f = open('chenli.txt') #開啟檔案
        first_line = f.readline()
        print('first line:',first_line) #讀一行
        data = f.read()# 讀取剩下的所有內容,檔案大時不要用
        print(data) #列印讀取內容
        f.close() #關閉檔案

2.檔案操作基本用法
    1)基本用法:
        file_object = open(file_name, access_mode = ‘r’, buffering = -1)
        open函式有很多的引數,常用的是file_name,mode和encoding
        file_name:開啟的檔名,若非當前路徑,需指出具體路徑
        access_mode檔案開啟模式
        buffering的可取值有0,1,>1三個,0代表buffer關閉(只適用於二進位制模式),1代表line buffer(只適用於文字模式),>1表示初始化的buffer大小; 
        encoding表示的是返回的資料採用何種編碼,一般採用utf8或者gbk;
    2)檔案開啟模式
        r ,只讀模式【預設模式,檔案必須存在,不存在則丟擲異常】
        w,只寫模式【不可讀;不存在則建立;存在則清空內容】
        x, 只寫模式【不可讀;不存在則建立,存在則報錯】
        a, 追加模式【可讀;   不存在則建立;存在則只追加內容】,檔案指標自動移到檔案尾。
        "+" 表示可以同時讀寫某個檔案
        r+, 讀寫【可讀,可寫】
        w+,寫讀【可讀,可寫】,消除檔案內容,然後以讀寫方式開啟檔案。
        x+ ,寫讀【可讀,可寫】
        a+, 寫讀【可讀,可寫】,以讀寫方式開啟檔案,並把檔案指標移到檔案尾。
         "b"表示以位元組的方式操作,以二進位制模式開啟檔案,而不是以文字模式。
         
        rb  或 r+b
        wb 或 w+b
        xb 或 w+b
        ab 或 a+b
         注:以b方式開啟時,讀取到的內容是位元組型別,寫入時也需要提供位元組型別,不能指定編碼
        import time
        三種基本的操作模式 r(只可讀) w(只可寫) a(追加)
        流程:1 建立檔案物件'小重山2' 2 呼叫檔案方法進行操作  3 關閉檔案

        data=open('小重山2','r',encoding='utf8').read()
        print(data)
             'r'表示讀模式  encoding='utf8'表示轉換字元 read()讀操作 ()內是幾就讀取幾個字元,不新增內容就是預設讀取全部內容
                f=open('小重山2','r',encoding='utf8')
                data=f.read(5)
                print(data)
            補充:
                python中有三個方法來處理檔案內容的讀取:
                read() #一次讀取全部的檔案內容。

                readline() #每次讀取檔案的一行。

                readlines() #讀取檔案的所有行,返回一個字串列表。
                print(f.readable())    #判斷檔案是否是r模式開啟的

                print(f.closed)    #判斷檔案是否是關閉狀態

                python中在文字檔案內容移動的操作
                file.seek(offset,whence=0)     #從檔案中給移動指標,從whence(0起始,1當前,2末尾)偏移offset個位元組,正往結束方向移動,負往開始方向移動
                file.tell()          #返回當前檔案中的位置。獲得檔案指標位置

                file.truncate(size=file.tell())    #擷取檔案到最大size個位元組,預設為當前檔案位置
        上述操作等於
        data=open('小重山2','r',encoding='utf8')
        f=data.read()
        print(f)4

        f=open('小重山2','r',encoding='utf8')
        f.write()#報錯
        f.close()
            讀寫模式必須一致,如下
        f=open('小重山2','w',encoding='utf8')
        f.write('hello world')
        f.close()
            補充:
                以w方式寫入檔案
                    f=open('a.txt','w',encoding='utf-8')
                    # f=open('b.txt','r',encoding='utf-8') #以讀的方式開啟檔案,檔案不存在則報錯
                    f=open('b.txt','w',encoding='utf-8')
                    # print(f.writable())

                    f.write('111111\n22222222')
                    f.seek(0)
                    f.write('\n333333\n444444')

                    f.writelines(['\n55555\n','6666\n','77777\n'])
                    f.close()

                    a.txt 為空
                    b.txt
                    333333
                    444444
                    55555
                    6666
                    77777
                     
                    file.write(str)     #向檔案中寫入字串(文字或二進位制)
                    file.writelines(seq)    #寫入多行,向檔案中寫入一個字串列表,注意,要自己加入每行的換行符
                    file.flush()    #重新整理檔案內部緩衝,直接把內部緩衝區的資料立刻寫入檔案, 而不是被動的等待輸出緩衝區寫入.
             注:當開啟的物件不存在時,會自動建立物件,存在時會先將物件格式化在寫內容
                    在第二遍執行寫操作時將不會再次格式化 而是直接緊跟在後面接著列印 若想換行或者空格 操作如下
                       f.write('hello world \n')
               若想對物件新增內容且不格式化原有內容可執行操作如下
                     f=open('小重山2','a',encoding='utf8')  #'a'表示append追加之意
                     f.write('\nhello world \n')
                     f.write('hel')
                     f.close()  注意:if not close,資料會快取,而不是磁碟!
            在對一個物件執行操作時 兩個程式可同時對同一個檔案執行操作,但 注意:程式程式結尾必須新增close 因為不知道程式什麼時候幫你執行結束,程式結束才會將資料提交到磁碟
                f=open('小重山2','r',encoding='utf8')
                f.write('\nhello world \n')
                f.write('alex')
                #注意:if not close,資料會快取,而不是磁碟!
                time.sleep(30) #讓程式執行30S
                f.close()
        若對檔案中間進行插入可執行如下
            data=open('小重山2','r',encoding='utf8')
            number = 0
            for i in data:
                number += 1
                if number == 6:
                    i = ''.join([i.strip(), 'iiiii'])  # 取代萬惡的+
                print(i.strip())
            f.close()
                或者:
            data=open('小重山2','r',encoding='utf8')
            number = 0
            for i in data:
                number += 1
                if number == 6:
                    print(i.strip(),'qqq')
                eslse
                    print(i.strip())
            f.close()
                但現實中不這樣實現,因為如果檔案過大不能將檔案 放置記憶體處理
            ##########對於大資料檔案,要用以下方式(the best way):
            # number=0
            # for i in f:#這是for內部將f物件做成一個迭代器,用一行去一行。
            #     number+=1
            #     if number == 6:
            #         i = ''.join([i.strip(), 'iiiii'])  # 取代萬惡的+
            #     #     print(i.strip())
            #     print(i.strip())    
        tell命令:與seek命令
            # print(f.tell())#  取出游標位置,
            # print(f.read(2))
            # print(f.tell()) #其中read中如果有中文則一箇中文會被識別為三個游標位
            #
            # f.seek(0)#  移動游標到指定的位置
            # print(f.read(4))
        flush命令:
            #flush():同步吧將資料從快取轉移到磁碟上去
            ##進度條例項
            # import sys,time
            # for i in range(30):
            #     sys.stdout.write("*")
            #     sys.stdout.flush()
            #     time.sleep(0.1)間隔0.1S輸出一個程式結果
           或者:
            #print的flush
            # import sys,time
            # for i in range(30):
            #     print('*',end='',flush=True)  #將flush作為一個引數使用
            #     time.sleep(0.1)
上下文管理with語句
    當你做檔案處理,你需要獲取一個檔案控制代碼,從檔案中讀取資料,然後關閉檔案控制代碼。
    正常情況下,程式碼如下:
    file = open("/tmp/foo.txt")
    data = file.read()
    file.close()
    這裡有兩個問題。一是可能忘記關閉檔案控制代碼;二是檔案讀取資料發生異常,沒有進行任何處理。
    然而with可以很好的處理上下文環境產生的異常。下面是with版本的程式碼:
    with open("/tmp /foo.txt") as file:
        data = file.read()
    with的基本思想是with所求值的物件必須有一個__enter__()方法,一個__exit__()方法。緊跟with後面的語句被求值後,返回物件的__enter__()方法被呼叫,這個方法的返回值將被賦值給as後面的變數。當with後面的程式碼塊全部被執行完之後,將呼叫前面返回物件的__exit__()方法。
     
    #with 同時管理多個檔案物件
    # with open('log1','r') as f_read, open('log2','w') as f_write:
    #     for line in f_read:
    #         f_write.write(line)
     
        補充:
        模擬   tail -f access.log

        #!/usr/bin/env python
        # -*- coding:utf-8 -*-

        # tail -f access.log
        import time
        with open('access.log','r',encoding='utf-8') as f:
            f.seek(0,2)
            while True:
                line=f.readline().strip()
                if line:
                    print('新增一行日誌',line)
                time.sleep(0.5)