1. 程式人生 > 實用技巧 >20201216-1 檔案讀與寫詳解3

20201216-1 檔案讀與寫詳解3

1-1
f = open("yesterday2",'r',encoding = "utf-8")   # 檔案控制代碼
print(f.tell())
--->
0
# 開啟檔案後,看游標的位置
# tell 列印游標的位置
1-1-1
f = open("yesterday2",'r',encoding = "utf-8")   # 檔案控制代碼
print(f.tell())
print(f.readline())
print(f.tell())
--->
0
Yesterday, all my troubles seemed so far away

47

多少個字元,就預設讀多少個數
1-1-2
可以指定讀取個數
f = open("yesterday2",'r',encoding = "utf-8")   # 檔案控制代碼
print(f.tell())
print(f.read(5))
print(f.tell())
--->
0
Yeste
5

tell() 是按字元計數的
1-1-3
f = open("yesterday2",'r',encoding = "utf-8")   # 檔案控制代碼
print(f.tell())
print(f.readline())
print(f.readline())
print(f.readline())
print
(f.tell()) ---> 0 Yesterday, all my troubles seemed so far away ����,���з�������ȥ Now it looks as though they're here to stay 122
1-1-4
f = open("yesterday2",'r',encoding = "utf-8")   # 檔案控制代碼
print(f.tell())
print(f.readline())
print(f.readline())
print(f.readline())
print(f.tell())
# 讀取三行內容後,想移回游標
# seek 是查詢游標 # 如果想回到第二行,回不去的,除非有記錄 f.seek(0) print(f.readline()) # seek 和 tell 搭配使用 ---> 0 Yesterday, all my troubles seemed so far away ����,���з�������ȥ Now it looks as though they're here to stay 122 Yesterday, all my troubles seemed so far away
1-1-5
f = open("yesterday2",'r',encoding = "utf-8")   # 檔案控制代碼
print(f.tell())
print(f.readline())
print(f.readline())
print(f.readline())
print(f.tell())
# 讀取三行內容後,想移回游標
# seek 是查詢游標
# 如果想回到第二行,回不去的,除非有記錄
f.seek(10)
print(f.readline())
--->
0
Yesterday, all my troubles seemed so far away

����,���з�������ȥ

Now it looks as though they're here to stay

122
 all my troubles seemed so far away

# 以上是 tell 和 seek 函式
1-2-1
encoding 列印檔案編碼
f = open("yesterday2",'r',encoding = "utf-8")   # 檔案控制代碼
print(f.encoding)
--->
utf-8
1-2-2
fileno 返回檔案控制代碼在檔案中的編號
f = open("yesterday2",'r',encoding = "utf-8")   # 檔案控制代碼
print(f.fileno())
--->
3
# 作業系統會有一個專門的介面 負責調動所有檔案,讀檔案不是python自己讀的
# 而是呼叫作業系統 io 讀取的
1-2-3
# name 就是列印檔名字
# isatty 檢視是否是終端裝置,比如和印表機的互動可能會用到
# seekable  比如 tty 檔案,終端裝置檔案是移不回去的,比如在 linux 上,一切皆檔案
# 如果是二進位制,字串是可以移動的,如果可以移動,返回true;否則,返回 false
# readable 是否可讀,writable 判斷是否可寫
1-2-4
# flush 重新整理

# 寫入檔案時,如果剛剛寫完一行斷電了,這一行,可能就沒有寫進去
# 因為這一行,可能還是在記憶體的快取中的
# 檔案讀寫有一個快取的機制,硬碟的讀寫比記憶體的讀寫慢
# 會導致瓶頸卡在這裡,必須寫到硬盤裡才可以繼續下一行
# 為了解決這個問題,沒寫完一行,暫時存在記憶體的快取裡,只要達到大小就一次性刷到硬碟上
# 所以寫的是一行,其實可能是若干行一起寫入的

# 這時有沒有一種可能要求資料的實時一致性?
# 要求 百分百確認,寫入了就是寫入了
# 確保快取裡的東西刷到硬碟,所以需要強制重新整理
# 比如存錢等場景,會用到

f = open("yesterday2",'w',encoding="utf-8")     # 檔案控制代碼
f.write("hello 1\n")
1-2-5
# 列印進度條,就是藉助 flush 方法
import sys

sys.stdout.write()
# sys.stdout 標準輸出
# sys.stdin  標準輸入
# write 操作螢幕,往螢幕上面輸出東西
>>> import sys
>>>
>>> sys.stdout.write("#")
#1
>>> sys.stdout.write("####")
####4
>>> sys.stdout.write("#######")
#######7
>>>       
1-2-6
import sys,time

for i in range(50):
    sys.stdout.write("#")
    time.sleep(1)
    # 預設不會換行,從前往後一點點排
1-2-7
import sys,time

for i in range(20):
    sys.stdout.write("#")
    # 這是等快取區滿了,統一打出來,所以需要重新整理
    sys.stdout.flush()    # 重新整理
    time.sleep(0.1)

# 螢幕也被當做一個檔案輸出,這個stdout.flush() 和前面的 flush 是一樣的
1-2-8
f.closed()   # 判斷檔案是否關閉 返回 true 或 false

f.truncate()  # 如果裡面什麼也不寫,檔案會被清空
1-2-9
f = open("yesterday2",'a',encoding="utf-8")
f.truncate(10) 
--->
Yesterday,

# 'w' 會清空,'w'是建立一個新檔案,改成 'a'
# 從檔案開頭,開始截斷 [指標在開頭]

1-2-9
f = open("yesterday2",'a',encoding="utf-8")
f.seek(10)
f.truncate(20) 
# 移動不好使,無論游標在哪裡,都是從頭開始截斷
2-1
# 既能讀,又可以寫入的方式,r+
f = open("yesterday2",'r+',encoding="utf-8")    # 檔案控制代碼
# r+ 就是讀寫,又能讀,又能寫
print(f.readline())
print(f.readline())
print(f.readline())
f.write("------- Wow -------")
print(f.readline())

--->
結果是 ------- Wow ------- 寫在了最後面
1-3
# 有讀寫,就有寫讀
# f = open("yesterday2",'r+',encoding="utf-8") # 檔案控制代碼 讀寫 
# f = open("yesterday2",'w+',encoding="utf-8") # 檔案控制代碼 寫讀
# 區別是,寫讀是先建立一個檔案,然後寫入

# 先建立檔案,寫四行
f = open("yesterday2",'w+',encoding="utf-8") 
f.write("------- Wow -------1\n")
f.write("------- Wow -------2\n")
f.write("------- Wow -------3\n")
f.write("------- Wow -------4\n")

# 列印位置
print(f.tell())
f.seek(10)
print(f.readline())
f.write("should be at the begining of the second line")

--->
------- Wow -------1
------- Wow -------2
------- Wow -------3
------- Wow -------4
should be at the begining of the second line

# 結果還是追加在後面了,沒有辦法在中間修改

# 寫讀模式,沒有什麼用處
# 讀寫模式,可以開啟,可以追加
1-3-1
# 還有一個追加讀
# f = open("yesterday2",'a+',encoding="utf-8") 追加讀寫
# 追加預設不能讀
# f = open("yesterday2",'r+',encoding="utf-8") 用的最多
1-3-2
# 還有一種模式
# f = open("yesterday2",'rb',encoding="utf-8")  以二進位制格式讀檔案
f = open("yesterday2",'rb',encoding="utf-8")
print(f.readline())
print(f.readline())
print(f.readline())
# 裡面的不是 二進位制 那麼能夠讀取嗎
--->
ValueError: binary mode doesn't take an encoding argument

# 二進位制的模式是不能傳 encoding 引數的
# 因為是 二進位制,所以不需要編碼了
1-3-3
f = open("yesterday2",'rb')
print(f.readline())
print(f.readline())
print(f.readline())
--->
b'------- Wow -------1\r\n'
b'------- Wow -------2\r\n'
b'------- Wow -------3\r\n'

# 結果也是能讀的
# 前面的 b 是 位元組型別,表示二進位制
# \r\n 是 windows 的換行格式

# python3 中 網路傳輸,只能用 二進位制
# 二進位制檔案 就用 二進位制開啟,網路傳輸,也用二進位制
1-3-4
# 有 rb 就有 wb
f = open("yesterday2",'wb')     
f.write("hello bianry\n")
f.close()
--->
TypeError: a bytes-like object is required, not 'str'

# 如何將 字串 轉換成 bytes? 用 encode
1-3-5
f = open("yesterday2",'wb')     
f.write("hello bianry\n".encode())
f.close()
# 沒有跟字符集,就預設使用程式的字符集
--->
hello bianry

# 預設 utf-8
# 二進位制不只是指 0101,是說這個檔案是以 二進位制編碼的;內部的處理是按二進位制處理
# 3.0 上需要明確區分,二進位制就是二進位制,字串就是字串