五、文件操作(二)

一、 可讀可寫:
# r+t  :可讀可寫 一打開光標就在開始位置
              直接寫將導致原始數據被覆蓋
# w+t:可讀可寫 一打開光標就在開始位置
             會把原始全都清空了
             要使用可讀可寫模式 首先要保證 你知道數據是如何編碼的
# a+t :  可讀可寫 一打開光標就在文件末尾

with open('a.txt',mode='r+t',encoding='utf-8') as f:
    print(f.readable())   #判斷是否可讀
    print(f.writable())    #判斷是否可寫
    msg=f.readline()         #只讀一行
    print(msg)
    f.write('xxxxxxxxxxx\n')
----------------------------------------------------
True
True

a.txt

xxxxxxxxxxx
 \n (回車)

二、控制文件內的指針移動

# 文件內指針移動,只有t模式下的read(n),n代表的字符的個數
# 除此以外文件內指針的移動都是以字節爲單位

with open('a.txt',mode='rt',encoding='utf-8') as f:
    msg=f.read(1)      #()不寫全部讀
    print(msg)
-------------------------------
x
# 使用b模式打開後轉成文本模式的使用decode解碼(指定編碼格式)
with open('a.txt',mode='rb') as f:
    msg=f.read(3)
    print(msg.decode('utf-8'))
-------------------------------------------
xxx

a.txt

xxxxxxxxxxx
   (\n 回車)

# f.seek(offset,whence)有兩個參數:
# offset: 代表控制指針移動的字節數
# whence: 代表參照什麼位置進行移動
#        whence = 0: 參照文件開頭(默認的),特殊???,可以在t和b模式下使用
#        whence = 1: 參照當前所在的位置,必須在b模式下用
#        whence = 2: 參照文件末尾,必須在b模式下用

a.txt

123456789
  1. py

with open('a.txt',mode='rt',encoding='utf-8') as f:
    f.seek(6,0)                 #從文件開頭,print 時會讀到下一個
    msg=f.read(1)
    print(msg)
-------------------------------------------------------------
7 

with open('a.txt',mode='rb') as f:
    f.seek(3,0)
    msg=f.read(3)
    print(msg.decode('utf-8'))   
-------------------------------------------
456 

with open('a.txt',mode='rb') as f:       
# utf-8中 b:模式是讀:“字節”(3個字節是一個字符) t:模式是字符(一個漢字)
    msg=f.read(3)
    print(msg.decode('utf-8'))
    print(f.tell())
    # f.seek(6,0)
    f.seek(3,1)
    msg1=f.read(3)
    print(msg1.decode('utf-8'))  
---------------------------------------------------
123
3
789
# 接上面 例子: 
with open("a.txt",'rb')as f:
    f.seek(8,0)
    print(f.read(1).decode('utf-8'))      
    # utf-8中 f.read("字節") b:模式是讀:“字節”(3個字節是一個字符) t:模式是字符(一個漢字)
    # 取字符e 
    # 取到第2個t
    # 如果一行都是(utf-8)中文,(b模式)都是按照3個字節是一個字符來算,若有中文也有英文,f.read(1) 應該按照一個字節取,中文還是算3個,若全是中文應該是f.read(3)
    # 因爲3個字節一箇中文

a.txt

×××
123456789
jkljkljhkljhkl

1.py

with open('a.txt',mode='rb') as f:
    msg=f.read(3)
    print(msg.decode('utf-8'))
    print(f.tell())     #統計文件的字符數,utf-8中 一箇中文字符佔3個字節數
    # f.seek(6,0)       # #0模式,是0模式往後移動的位置再在當前光標處繼續移動 字節(b模式的話)。
    f.seek(3,1)         #如果最開始用1模式的話,是與0模式效果一樣,因爲都是從光標開頭出開始
    msg1=f.read(3)
    print(msg1.decode('utf-8'))
----------------------------------------------
中
3
人
  1. py

with open('a.txt',mode='rb') as f:
    # f.seek(0,2)
    # print(f.tell())
    f.seek(-3,2)        # 2模式前面必須是負數,因爲正數的話是往後取值(2模式本來就是文件末尾)
    msg=f.read(3)
    print(msg.decode('utf-8'))
--------------------------------------
hkl
with open('access.log',mode='rb') as f:
    f.seek(0,2) # 當前位置是147bytes
    while True:
        line=f.readline() # 當前位置是196bytes
        # print(f.tell())
        if len(line) == 0:
            # 沒有新的一行內容追加進來
            pass
        else:
            # 有新的一行內容追加進來
            print(line.decode('utf-8'),end='')
with open('access.log',mode='rb') as f:
    f.seek(0,2) # 當前位置是147bytes
    while True:
        line=f.readline() # 當前位置是196bytes
        if len(line) != 0:
            print(line.decode('utf-8'),end='')
with open('a.txt',mode='r+t',encoding='utf-8') as f:
    f.truncate(6)

a.txt (舊)

×××

a.txt (新)

中華
import time

with open('access.log','at',encoding='utf-8') as f:
    f.write('%s alex給egon轉賬了1個億\n' %time.strftime('%Y-%m-%d %H:%M:%S'))


三、文件修改的兩種方式

# 修改文件的方式一:
# 1 將文件內容由硬盤全部讀入內存
# 2 在內存中完成修改
# 3 將內存中修改後的結果覆蓋寫回硬盤

a.txt

alex
  1. py (將文件a.txt中的alex修改成爲"dsb")

with open('a.txt',mode='rt',encoding='utf-8') as f:
    all_data=f.read()
print(all_data,type(all_data))
with open('a.txt',mode='wt',encoding='utf-8') as f:
    f.write(all_data.replace('alex','dsb'))

# 修改文件的方式二:  (將文件a.txt中的"alex"修改成爲"dsb")

# 1 以讀的方式打開源文件,以寫的方式打開一個臨時文件
# 2 從源文件中每讀一樣內容修改完畢後寫入臨時文件,直到源文件讀取完畢
# 3 刪掉源文件,將臨時文件重命名爲源文件名

import os
with open('a.txt',mode='rt',encoding='utf-8') as read_f,open('.a.txt.swap',mode='wt',encoding='utf-8') as write_f:
    for line in read_f:
        write_f.write(line.replace('alex','dsb'))
os.remove('a.txt')
os.rename('.a.txt.swap','a.txt')

# 方式一:
# 優點: 在文件修改的過程中硬盤上始終一份數據
# 缺點: 佔用內存過多,不適用於大文件


# 方式二:
# 優點: 同一時刻在內存中只存在源文件的一行內容,不會過多地佔用內存
# 缺點: 在文件修改的過程中會出現源文件與臨時文件共存,硬盤上同一時刻會有兩份數據,即在修改的過程中會過多的佔用硬盤,


# 把列表寫入到文件中

# 將列表轉成字符,然後再寫入到文件中

l=[1,2,3,'a','b','c','d']
with open ("c.txt",'w+t',encoding='utf-8') as f:
    f.write(str(l))

c.txt

[1, 2, 3, 'a', 'b', 'c', 'd']





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章