Was ist der beste Weg, um eine Datei für den exklusiven Zugriff in Python zu öffnen?
Was ist der eleganteste Weg, um dieses Problem zu lösen:
- öffnen einer Datei zum Lesen, aber nur, wenn es nicht bereits geöffnet ist für schreiben
- öffnen einer Datei zum schreiben, aber nur, wenn es nicht schon zum Lesen oder schreiben geöffnet
Den built-in-Funktionen arbeiten wie diese
>>> path = r"c:\scr.txt"
>>> file1 = open(path, "w")
>>> print file1
<open file 'c:\scr.txt', mode 'w' at 0x019F88D8>
>>> file2 = open(path, "w")
>>> print file2
<open file 'c:\scr.txt', mode 'w' at 0x02332188>
>>> file1.write("111")
>>> file2.write("222")
>>> file1.close()
scr.txt enthält nun '111'.
>>> file2.close()
scr.txt überschrieben und enthält nun '222' (auf Windows, Python 2.4).
Die Lösung sollte funktionieren in dem selben Prozess (wie im Beispiel oben), als auch, wenn ein anderer Prozess die Datei geöffnet hat.
Es ist bevorzugt, wenn ein Programm abstürzt, wird nicht halten Sie das Schloss öffnen.
Kommentar zu dem Problem
wollen Sie exklusive öffnen von Dateien innerhalb Ihrer eine Anwendung (so dass Sie nicht überschreiben einer Datei die änderungen mit anderen Datei-Objekt verweist auf derselben Stelle)? Oder meinst du einen global-lock?
InformationsquelleAutor der Frage mar10 | 2008-10-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich glaube nicht, dass es eine komplett plattformübergreifende Art und Weise. Auf unix, dem fcntl-Modul wird dies für Sie tun. Allerdings auf windows (ich nehme an, Sie sind durch die Pfade), die Sie benutzen müssen win32file-Modul.
Glücklicherweise gibt es eine portable Implementierung ( portalocker ), die über die Plattform geeignete Methode an das python-Kochbuch.
Um es zu verwenden, öffnen Sie die Datei, und rufen Sie dann:
wo Fahnen sind portalocker.LOCK_EX für exklusiven Schreibzugriff oder LOCK_SH für shared, read-Zugriff.
InformationsquelleAutor der Antwort Brian
Wenn von 'einem anderen Prozess' du meinst 'was auch immer Prozess' (also nicht Programm), in Linux gibt es keine Möglichkeit, dies zu erreichen verlassen Sie sich nur auf system calls (fcntl & friends). Was Sie wollen, ist mandatory locking, und der Linux-Weg zu erhalten es wird ein bisschen mehr beteiligt:
Remount der partition, auf der Sie Ihre Datei mit der mand option:
Legen Sie die sgid flag für die Datei:
In Ihrem Python-code, erhalten eine exklusive Sperre auf die Datei:
Nun auch Katze nicht in der Lage, die Datei zu Lesen, bis Sie die Sperre wieder freigeben.
InformationsquelleAutor der Antwort Federico A. Ramponi
Hier ist ein Anfang auf der win32-Hälfte eine portable Implementierung, die nicht brauchen, eine separate Verriegelung.
Erfordert die Python for Windows Extensions, um sich um die win32 api, aber das ist so ziemlich Pflicht für python auf windows schon, und kann alternativ durchgeführt werden, die mit ctypes. Der code kann angepasst werden, um weitere Funktionen verfügbar machen, wenn es gebraucht wird (wie beispielsweise die Möglichkeit
FILE_SHARE_READ
eher als kein teilen). Siehe auch in der MSDN-Dokumentation für dieCreateFile
undWriteFile
system fordert, und die Artikel zum Erstellen und Öffnen von Dateien.Wie bereits erwähnt, können Sie das standard - fcntl Modul zu implementieren, die die unix-Hälfte, wenn erforderlich.
Hier erfahren Sie, wie Ihre obige Beispiel verhält:
InformationsquelleAutor der Antwort gz.
EDIT: ich löste es selbst! Durch die Verwendung Verzeichnis Existenz & Alter als einen locking-Mechanismus! Sperren von Datei sicher nur auf Windows (weil Linux schweigend überschreibt), aber das sperren von Verzeichnissen funktioniert perfekt sowohl auf Linux und Windows. Siehe mein GIT, wo ich einen leicht zu bedienenden Klasse 'lockbydir.DLock':
https://github.com/drandreaskrueger/lockbydir
Unten in der readme-Datei finden Sie 3 GITplayers wo sehen Sie die code-Beispiele führen Sie live in Ihrem browser! Ziemlich cool, nicht wahr? 🙂
Vielen Dank für Ihre Aufmerksamkeit
Dies war meine ursprüngliche Frage:
Ich würde gerne, Sie zu beantworten parity3 ( https://meta.stackoverflow.com/users/1454536/parity3 ), aber ich kann weder Kommentare direkt ('Sie müssen die 50 Ruf zu Kommentar'), noch sehe ich irgendeine Möglichkeit, ihn zu Kontaktieren/Ihr direkt. Was empfehlen Sie mir, um durch ihn bekommen?
Meine Frage:
Implementierte ich etwas ähnliches zu dem, was parity3 vorgeschlagen, hier eine Antwort: https://stackoverflow.com/a/21444311/3693375 ("wenn der Python-interpreter und das ...")
Und es hervorragend funktioniert - unter Windows. (Ich benutze es zur Implementierung eines locking-Mechanismus, der funktioniert unabhängig über gestartete Prozesse. https://github.com/drandreaskrueger/lockbyfile )
Aber anders als parity3 sagt, es funktioniert NICHT das gleiche unter Linux:
Silent einbauen ist das problem. Auf Linux.
"Wenn die Sommerzeit bereits vorhanden ist, OSError wird erhöht werden" ist ideal für meine Zwecke. Aber nur auf Windows, leider.
Ich denke, parity3 das Beispiel funktioniert immer noch die meiste Zeit, weil seine if-Bedingung
Dann aber das ganze ist nicht atomar mehr.
Weil die if-Bedingung wahr sein könnte, zwei parallele Prozesse, und dann beide umbenennen, aber nur einer wird gewinnen die Umbenennung Rennen. Und keine Ausnahme ausgelöst wird (in Linux).
Irgendwelche Vorschläge? Danke!
P. S.: ich weiß, das ist nicht der richtige Weg, aber mir fehlt eine alternative. BITTE nicht bestrafen mich mit der Absenkung mein Ruf. Ich schaute mich um eine Menge, um dieses Problem zu lösen mich. Wie Sie PM-Benutzer hier? Und meh warum kann ich nicht?
InformationsquelleAutor der Antwort akrueger
Stellen Sie sicher, wenn Sie Dateien öffnen in einer Anwendung, die Sie könnten versuchen, so etwas wie dieses:
So dass Sie eine Unterklasse der
file
Klasse. Jetzt nur:Wenn Sie öffnen Sie es zuerst mit 'w' - Modus, es nicht zulassen, dass mehr öffnet, auch im lese-Modus, genau wie Sie es wollten...
InformationsquelleAutor der Antwort kender
Vorausgesetzt, Ihr Python-interpreter und das darunter liegende os und Dateisystem behandeln os.benennen Sie als eine Atomare operation, und es werden Fehler, wenn das Ziel vorhanden ist, die folgende Methode ist frei von race conditions. Ich bin mit in die Produktion auf einem linux-Rechner. Erfordert keine Drittanbieter-libs und ist nicht os-abhängig, und abgesehen von einer extra-Datei erstellen, die Leistung der Treffer ist akzeptabel für viele Anwendungsfälle. Sie können leicht anwenden-python-Funktion Dekorator-Muster oder ein "with_statement' contextmanager hier zu abstrahieren, aus dem Schlamassel.
Müssen Sie sicherstellen, dass lock_filename nicht vorhanden ist, bevor ein neuer Vorgang/Vorgang beginnt.
BEARBEITEN
Es ist gekommen, um Licht, das os.benennen Sie leise überschreibt das Ziel auf einer nicht-windows-OS. Vielen Dank für diesen Hinweis @ akrueger!
Hier ist eine Abhilfe, die sich aus hier:
Anstelle von os.umbenennen Sie verwenden können:
@ akrueger sind Sie wahrscheinlich gut mit Ihren directory-basierte Lösung, nur geben Sie eine Alternative Methode.
InformationsquelleAutor der Antwort parity3