[英]Is Path.replace equivalent to os.replace or shutil.move?
[英]os.rename, os.replace and shutil.move errors on windows 10
我試圖在Windows 10上使用重命名來實現簡單的文件鎖定。我有以下測試程序,該程序重命名文件以將其鎖定,然后打開並讀取它,然后重命名以對其進行解鎖。 但是,當我使用不同的參數同時運行其中兩個時,出現間歇性錯誤(例如test.py 1,test.py 2)
import sys
import os
from time import sleep
import shutil
def lockFile():
while True:
try:
os.replace("testfile", "lockfile"+sys.argv[1])
if(os.path.exists("lockfile"+sys.argv[1])):
print("successfully locked", flush=True)
print(os.stat("lockfile"+sys.argv[1]))
else:
print("failed to lock", flush=True)
raise BaseException()
return
except:
print("sleeping...", flush=True)
sleep(1)
def unlockFile():
while True:
try:
os.replace("lockfile"+sys.argv[1], "testfile")
if(os.path.exists("testfile")):
print("successfully unlocked", flush=True)
else:
print("failed to unlock", flush=True)
raise BaseException()
return
except:
print("sleeping...", flush=True)
sleep(1)
while True:
lockFile()
if(os.path.exists("lockfile"+sys.argv[1])):
print("file is available", flush=True)
else:
print("file is not available", flush=True)
with open(("lockfile"+sys.argv[1])) as testFile:
contents = testFile.read()
print(contents.rstrip(), flush=True)
unlockFile()
我看到的是,偶爾重命名/替換/移動不會引發異常,os.path.exists表示存在鎖定文件,我可以統計鎖定文件,然后突然鎖定文件消失了,我無法打開它:
successfully locked
os.stat_result(st_mode=33206, st_ino=9288674231797231, st_dev=38182903, st_nlink=1, st_uid=0, st_gid=0, st_size=12, st_atime=1536956584, st_mtime=1536956584, st_ctime=1536942815)
file is not available
Traceback (most recent call last):
File "test.py", line 41, in <module>
with open(("lockfile"+sys.argv[1])) as testFile:
FileNotFoundError: [Errno 2] No such file or directory: 'lockfile2'
我認為部分問題是os.path.exists說謊
目錄將文件名緩存到文件句柄映射。 最常見的問題是:
•您有一個打開的文件,需要檢查該文件是否已被較新的文件替換。 您必須先刷新父目錄的文件句柄緩存,然后stat()返回新文件的信息,而不返回打開文件的信息。
◦實際上,這種情況還存在另一個問題:舊文件可能已被刪除並被新文件替換,但是兩個文件可能具有相同的inode。 您可以通過刷新打開文件的屬性高速緩存,然后查看fstat()是否因ESTALE失敗而檢查這種情況。
•您需要檢查文件是否存在。 例如一個鎖定文件。 內核可能已緩存該文件不存在,即使實際上確實存在。 您必須刷新父目錄的負文件句柄緩存,以查看該文件是否確實存在。
因此,有時當您的函數正在檢查lockFile()函數中是否存在該路徑時,實際上並不存在該路徑。
好的,根據上面鏈接的帖子, os.path位於 ,我拼湊了一個解決方案。 這可能仍然只是幸運的時機,目前僅適用於Windows。 如果我在執行os.path.exists檢查之前將subprocess.Popen更改為重命名/替換或省略os.stat,則它不起作用。 但是這段代碼似乎沒有解決問題。 使用5個同時運行的腳本進行了測試,並且沒有睡眠調用。
def lockFile():
while True:
try:
p = subprocess.Popen("rename testfile lockfile"+sys.argv[1], shell=True,
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
result = p.wait()
statresult = os.stat("lockfile"+sys.argv[1])
if(os.path.exists("lockfile"+sys.argv[1])):
print("successfully locked", flush=True)
print(os.stat("lockfile"+sys.argv[1]), flush=True)
else:
print("failed to lock", flush=True)
raise BaseException()
return
except BaseException as err:
print("sleeping...", flush=True)
#sleep(1)
def unlockFile():
while True:
try:
p = subprocess.Popen("rename lockfile"+sys.argv[1] + " testfile", shell=True,
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
result = p.wait()
statresult = os.stat("testfile")
if(os.path.exists("testfile")):
pass
else:
print("failed to unlock", flush=True)
raise BaseException()
return
except BaseException as err:
print("sleeping...", flush=True)
#sleep(1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.