python 檔案原子寫入
1. 檔案原子寫入
你的**以寫的方式開啟了乙個檔案,執行寫入操作,但在寫入過程中,發生了異常,導致程式崩潰,這個時候,檔案裡已經有了一部分你寫入的資料,但是不完整,這往往是乙個不被接受的結果。檔案原子寫入,是指一次寫入操作,要麼是全部資料都寫入檔案,要麼是全部資料都沒有寫入檔案。
下面通過乙個實驗,來解釋檔案原子寫入的必要性
with open('userlist1', 'w')as f:
f.write('xiaohong\n')
f.flush()
0 / 0
f.write('xiaogang\n')
**建立乙個userlist1檔案,希望能寫入兩個學生的姓名,但是恰好發生了異常,這時,檔案已經被建立,而且xiaohong已經被寫入到檔案中,如果程式在其他地方捕獲了這個異常卻沒有提醒你,那麼你可能以為這次寫入操作是正常的,或者僅僅從結果上看,檔案確實建立了,而且裡面有資料,但資料不是全部,有一部分缺失。
2. 借助臨時檔案
為了實現檔案原子寫入,乙個簡單可行的思路是借助臨時檔案,先將資料寫入到臨時檔案,臨時檔案寫入成功以後再將檔案重新命名,這樣,就不存在寫入部分資料的情況了。
import os
f = open('userlist1_tmp', 'w')
f.write('xiaohong\n')
# 0/0
f.write('xiaogang\n')
f.flush() # 確保資料寫入磁碟
os.fsync(f.fileno())
f.close()
os.rename('userlist1_tmp', 'userlist1')
注意這段**並不會保證寫檔案不發生異常,如果將0/0 這行**的注釋去掉,異常同樣會發生,但這時,只有userlist1_tmp被建立,最終的目標檔案userlist1 是不會被建立的,通過這種方式,就確保檔案寫入是原子的,不會出現部分資料被寫入,部分資料未被寫入的情況。
3. python-atomicwrites
上面的**只是一種簡單的實現,有許多特殊情況是沒有被考慮的,比如臨時檔案和目標檔案不在同乙個檔案系統上,那麼也不是原子操作,同時這段**也沒有考慮跨平台的問題,這裡推薦乙個開源庫python-atomicwrites, 使用pip install atomicwrites 進行安裝。作者已經幫我們盡可能的處理了這些特殊情況,因此可以放心使用,我使用這個開源庫來實現檔案的原子寫入
from atomicwrites import atomic_write
with atomic_write('userlist1', overwrite=true) as f:
f.write('xiaohong\n')
# 0/0
f.write('xiaogang\n')
原子性,原子操作
舉個例子 a想要從自己的帳戶中轉1000塊錢到b的帳戶裡。那個從a開始轉帳,到轉帳結束的這乙個過程,稱之為乙個事務。在這個事務裡,要做如下操作 從a的帳戶中減去1000塊錢。如果a的帳戶原來有3000塊錢,現在就變成2000塊錢了。在b的帳戶裡加1000塊錢。如果b的帳戶如果原來有2000塊錢,現在...
原子性atomic與非原子性natomic
原子操作是不可分割的操作,在原子操作執行完畢之前,其不會被任何其它任務或事件中斷。在單處理器系統 uniprocessor 中,能夠在單條指令中完成的操作都可以認為是 原子操作 因為中斷只能發生於指令之間。某些cpu指令系統中引入了test and set test and clear等指令產生臨界...
mysql原子性 MySQL事務的原子性
一 事務的acid特性 1 原子性 2 一致性 3 隔離性 4 永續性 二 對於事務的原子性 a 我們知道事務中的操作要麼都做要麼都不做。對於這一點許多人有錯誤的理解,我們來看乙個例子 1 mysql select from t4 id name 1 a 2 b 3 c 3 rows in set ...