215 Stimmen

Sperren einer Datei in Python

Ich muss eine Datei zum Schreiben in Python sperren. Auf die Datei wird von mehreren Python-Prozessen gleichzeitig zugegriffen. Ich habe im Internet einige Lösungen gefunden, aber die meisten sind für meine Zwecke ungeeignet, da sie oft nur auf Unix oder Windows basieren.

172voto

Evan Fosmark Punkte 93825

In Ordnung, also habe ich mich für den Code entschieden, den ich geschrieben habe hier, auf meiner Website Link ist tot, Ansicht auf archive.org ( auch auf GitHub verfügbar ). Ich kann sie auf folgende Weise verwenden:

from filelock import FileLock

with FileLock("myfile.txt"):
    # work with the file as it is now locked
    print("Lock acquired.")

55voto

Thomas Lux Punkte 868

Die anderen Lösungen zitieren eine Menge externer Codebasen. Wenn Sie es lieber selbst machen möchten, finden Sie hier einige Codes für eine plattformübergreifende Lösung, die die entsprechenden Dateisperrwerkzeuge auf Linux-/DOS-Systemen verwendet.

try:
    # Posix based file locking (Linux, Ubuntu, MacOS, etc.)
    #   Only allows locking on writable files, might cause
    #   strange results for reading.
    import fcntl, os
    def lock_file(f):
        if f.writable(): fcntl.lockf(f, fcntl.LOCK_EX)
    def unlock_file(f):
        if f.writable(): fcntl.lockf(f, fcntl.LOCK_UN)
except ModuleNotFoundError:
    # Windows file locking
    import msvcrt, os
    def file_size(f):
        return os.path.getsize( os.path.realpath(f.name) )
    def lock_file(f):
        msvcrt.locking(f.fileno(), msvcrt.LK_RLCK, file_size(f))
    def unlock_file(f):
        msvcrt.locking(f.fileno(), msvcrt.LK_UNLCK, file_size(f))

# Class for ensuring that all file operations are atomic, treat
# initialization like a standard call to 'open' that happens to be atomic.
# This file opener *must* be used in a "with" block.
class AtomicOpen:
    # Open the file with arguments provided by user. Then acquire
    # a lock on that file object (WARNING: Advisory locking).
    def __init__(self, path, *args, **kwargs):
        # Open the file and acquire a lock on the file before operating
        self.file = open(path,*args, **kwargs)
        # Lock the opened file
        lock_file(self.file)

    # Return the opened file object (knowing a lock has been obtained).
    def __enter__(self, *args, **kwargs): return self.file

    # Unlock the file and close the file object.
    def __exit__(self, exc_type=None, exc_value=None, traceback=None):        
        # Flush to make sure all buffered contents are written to file.
        self.file.flush()
        os.fsync(self.file.fileno())
        # Release the lock on the file.
        unlock_file(self.file)
        self.file.close()
        # Handle exceptions that may have come up during execution, by
        # default any exceptions are raised to the user.
        if (exc_type != None): return False
        else:                  return True        

Jetzt, AtomicOpen kann in einem with Block, wo man normalerweise eine open Erklärung.

WARNUNGEN:

  • Wenn Python unter Windows läuft und abstürzt, bevor Ausgang aufgerufen wird, bin ich mir nicht sicher, wie sich die Sperre verhalten würde.
  • Die hier angegebene Verriegelung ist beratend, nicht absolut. Alle potenziell konkurrierenden Prozesse müssen die Klasse "AtomicOpen" verwenden.
  • Ab dem (9. November 2020) sperrt dieser Code nur noch beschreibbar Dateien auf Posix-Systemen. Irgendwann nach der Veröffentlichung und vor diesem Datum wurde es illegal, die fcntl.lock bei schreibgeschützten Dateien.

44voto

John Fouhy Punkte 39035

Hier gibt es ein plattformübergreifendes Dateisperrmodul: Portalocker

Obwohl, wie Kevin sagt, das Schreiben in eine Datei von mehreren Prozessen aus gleichzeitig etwas ist, das man nach Möglichkeit vermeiden sollte.

Wenn Sie Ihr Problem in eine Datenbank zwängen können, könnten Sie SQLite verwenden. Es unterstützt gleichzeitigen Zugriff und verwaltet seine eigenen Sperren.

26voto

Maxime Viargues Punkte 1005

Ich habe mir verschiedene Lösungen dafür angeschaut, und meine Wahl fiel auf oslo.nebenläufigkeit

Sie ist leistungsstark und relativ gut dokumentiert. Es basiert auf Verbindungselementen.

Andere Lösungen:

18voto

ferrdo Punkte 187

Ich bevorzuge Sperrdatei - Plattformunabhängige Dateisperre

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X