簡體   English   中英

Windows 10上的os.rename,os.replace和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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM