Khóa tệp Python

FileLock được sử dụng để chỉ ra một quy trình khác trong ứng dụng của bạn rằng tài nguyên hoặc thư mục làm việc hiện đang được sử dụng. Để làm như vậy, trước tiên hãy tạo FileLock

from filelock import Timeout, FileLock

file_path = "high_ground.txt"
lock_path = "high_ground.txt.lock"

lock = FileLock(lock_path, timeout=1)

Đối tượng khóa hỗ trợ nhiều cách để lấy khóa, bao gồm cả những cách được sử dụng để lấy khóa chuỗi Python tiêu chuẩn

with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()

Phương thức thu được cũng chấp nhận một tham số hết thời gian chờ. Nếu khóa không thể lấy được trong vài giây hết thời gian chờ, một ngoại lệ Hết thời gian chờ sẽ được nâng lên

try:
    with lock.acquire(timeout=10):
        with open(file_path, "a") as f:
            f.write("I have a bad feeling about this.")
except Timeout:
    print("Another instance of this application currently holds the lock.")

Các đối tượng khóa là các khóa đệ quy, có nghĩa là sau khi có được, chúng sẽ không chặn các yêu cầu khóa liên tiếp

Đôi khi, bạn có thể cần khóa một tệp hoặc thư mục khỏi ứng dụng hoặc dịch vụ python của mình để ngăn người khác sửa đổi nó. Điều này được yêu cầu đặc biệt nếu nhiều quy trình đang truy cập cùng một tệp. Nói chung, khóa tệp được triển khai bằng các công cụ hệ điều hành trong Linux và Windows. Nhưng đôi khi bạn có thể cần thực thi khóa tệp từ bên trong python. Trong bài viết này, chúng ta sẽ tìm hiểu cách khóa tệp trong python. Bạn có thể sử dụng các bước này trên tất cả các phiên bản Python, từ bên trong các ứng dụng, tập lệnh, dịch vụ dựa trên python của bạn và thậm chí cả các trang web


Cách khóa tệp trong Python

Có một số thư viện có sẵn để khóa tệp. Chúng tôi sẽ sử dụng Portalocker cho mục đích của chúng tôi. Portalocker cung cấp một API dễ dàng để khóa tệp trong python. Nó thậm chí còn hỗ trợ khóa Redis

Đây là lệnh để cài đặt Portalocker

pip install portalocker

Nếu bạn sử dụng Python<2, thay vào đó hãy sử dụng lệnh sau để cài đặt cổng thông tin

pip install "portalocker<2"

Khi Portalocker được cài đặt, bạn có thể sử dụng nó như hình bên dưới để khóa tệp kiểm tra. txt

import portalocker

with portalocker.Lock('test.txt') as fh:
    fh.write('first instance')
    ...

Về cơ bản, chúng tôi gọi cổng thông tin điện tử. Lock() để khóa một tập tin. Khi nó bị khóa, các quy trình khác sẽ không thể sửa đổi nó miễn là nó bị khóa

Nếu bạn đang gọi khóa tệp qua mạng, thì bạn có thể cần gọi os. fsync() trước khi đóng tệp để thực sự ghi tất cả các thay đổi trước khi người khác có thể đọc chúng

with portalocker.Lock('test.txt', 'rb+', timeout=60) as fh:
    # do what you need to do
    ...

    # flush and sync to filesystem
    fh.flush()
    os.fsync(fh.fileno())

Xin lưu ý, các khóa này có tính chất tư vấn trong các hệ thống Linux/Unix, đây là cài đặt mặc định trong các Hệ điều hành này. Nếu bạn muốn chúng là bắt buộc thì bạn cần gắn hệ thống tệp với tùy chọn mand

Xin lưu ý, giải pháp này không hoàn hảo. Nếu chương trình python của bạn kết thúc đột ngột, tệp này sẽ tiếp tục bị khóa và bạn sẽ phải mở khóa thủ công. Tuy nhiên, đó là một giải pháp tốt

Bạn cần khóa tệp theo cách đa nền tảng giữa NT và Posix, nhưng thư viện chuẩn Python chỉ cung cấp các cách khóa tệp dành riêng cho nền tảng

Khi bản thân thư viện chuẩn Python không cung cấp giải pháp đa nền tảng, bạn thường có thể tự triển khai một giải pháp

import os

# needs win32all to work on Windows
if os.name == 'nt':
    import win32con, win32file, pywintypes
    LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK
    LOCK_SH = 0 # the default
    LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY
    _ _overlapped = pywintypes.OVERLAPPED(  )

    def lock(file, flags):
        hfile = win32file._get_osfhandle(file.fileno(  ))
        win32file.LockFileEx(hfile, flags, 0, 0xffff0000, _ _overlapped)

    def unlock(file):
        hfile = win32file._get_osfhandle(file.fileno(  ))
        win32file.UnlockFileEx(hfile, 0, 0xffff0000, _ _overlapped)
elif os.name == 'posix':
    from fcntl import LOCK_EX, LOCK_SH, LOCK_NB

    def lock(file, flags):
        fcntl.flock(file.fileno(  ), flags)

    def unlock(file):
        fcntl.flock(file.fileno(  ), fcntl.LOCK_UN)
else:
    raise RuntimeError("PortaLocker only defined for nt and posix platforms")

Nếu bạn có nhiều chương trình hoặc luồng có thể muốn truy cập vào một tệp được chia sẻ, bạn nên đảm bảo rằng các truy cập được đồng bộ hóa để hai quy trình không cố gắng sửa đổi nội dung tệp cùng một lúc. Không làm như vậy có thể làm hỏng toàn bộ tệp trong một số trường hợp

Công thức này cung cấp hai hàm,

with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
3 và
with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
4, lần lượt yêu cầu và giải phóng các khóa trên một tệp. Sử dụng mô-đun
with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
5 là một vấn đề đơn giản khi gọi hàm
with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
3 và chuyển vào tệp và một đối số chỉ định loại khóa mong muốn

with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
7

Khóa dùng chung (giá trị mặc định). Điều này từ chối tất cả các quy trình ghi quyền truy cập vào tệp, bao gồm cả quy trình đầu tiên khóa tệp. Tất cả các quy trình có thể đọc tệp bị khóa

with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
8

Khóa độc quyền. Điều này từ chối tất cả các quy trình khác cả quyền truy cập đọc và ghi vào tệp

with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
9

Khóa không chặn. Nếu giá trị này được chỉ định, hàm sẽ trả về ngay lập tức nếu không thể lấy khóa được yêu cầu. Còn không thì nó đợi.

with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
9 có thể được ORed với
with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
7 hoặc
with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
8

Ví dụ

________số 8

Việc triển khai các chức năng

with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
3 và
with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
4 hoàn toàn khác nhau trên các hệ thống giống Unix (nơi chúng có thể dựa vào chức năng do mô-đun
import portalocker
file = open("somefile", "r+")
portalocker.lock(file, portalocker.LOCK_EX)
4 tiêu chuẩn cung cấp) và trên các hệ thống Windows (nơi chúng phải sử dụng mô-đun
import portalocker
file = open("somefile", "r+")
portalocker.lock(file, portalocker.LOCK_EX)
5, một phần của
import portalocker
file = open("somefile", "r+")
portalocker.lock(file, portalocker.LOCK_EX)
6 rất phổ biến . Nhưng điều quan trọng là, bất chấp sự khác biệt trong cách triển khai, các hàm (và các cờ bạn có thể chuyển đến hàm
with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
3) hoạt động theo cùng một cách trên các nền tảng. Việc đóng gói đa nền tảng như vậy với chức năng tương đương nhưng được triển khai khác nhau là thứ cho phép bạn viết các ứng dụng đa nền tảng, đây là một trong những điểm mạnh của Python

Khi bạn viết một chương trình đa nền tảng, thật tuyệt nếu chức năng mà chương trình của bạn sử dụng lại được gói gọn theo cách đa nền tảng. Đặc biệt, đối với khóa tệp, điều này hữu ích cho người dùng Perl, những người đã quen với lệnh gọi hệ thống

with lock:
    with open(file_path, "a") as f:
        f.write("Hello there!")

lock.acquire()
try:
    with open(file_path, "a") as f:
        f.write("General Kenobi!")
finally:
    lock.release()


@lock
def decorated():
    print("You're a decorated Jedi!")


decorated()
3 về cơ bản minh bạch trên các nền tảng. Tổng quát hơn,
import portalocker
file = open("somefile", "r+")
portalocker.lock(file, portalocker.LOCK_EX)
9 không thuộc mã cấp ứng dụng. Lý tưởng nhất là nó luôn nằm trong thư viện chuẩn hoặc một mô-đun độc lập với ứng dụng, như ở đây

Làm cách nào để khóa một tệp trong Python?

Gói này chứa một mô-đun duy nhất, thực hiện khóa tệp độc lập với nền tảng trong Python, cung cấp một cách đơn giản để giao tiếp giữa các quá trình. từ filelock hết thời gian nhập, FileLock lock = FileLock("high_ground. txt.

Tệp khóa trong Python là gì?

lockfile cho Python là gì? . Một số cơ chế khóa khác nhau được hỗ trợ bằng API chung. provides a platform-independent advisory file locking capability for Python applications. Several different lock mechanisms are supported using a common API.

Làm cách nào để cài đặt FileLock trong Python?

Gõ "cmd" vào thanh tìm kiếm và nhấn Enter để mở dòng lệnh. Đây là gì? Nhập “ pip install filelock ” (không có dấu ngoặc kép) trong dòng lệnh và nhấn Enter lần nữa . Thao tác này sẽ cài đặt khóa tệp cho cài đặt Python mặc định của bạn.

Mục đích của việc khóa tập tin là gì?

Khóa tệp là một tính năng quản lý dữ liệu hạn chế người dùng khác thay đổi một tệp cụ thể . Điều này chỉ cho phép một người dùng hoặc quy trình truy cập vào tệp này tại bất kỳ thời điểm nào. Điều này là để ngăn vấn đề cập nhật xen kẽ trên cùng một tệp.