8
Mới! Lưu câu hỏi hoặc câu trả lời và sắp xếp nội dung yêu thích của bạn. Tìm hiểu thêm.
Learn more.
Trong mã luồng của tôi, tôi cần chờ một tệp được mở khóa để xử lý nó hơn nữa.
Tệp có khả năng bị khóa bởi [các] luồng nước ngoài mà tôi không thể kiểm soát.
Hiện tại tôi sử dụng mã này trong chuỗi của mình:
...
while IsFileInUse[FileName] and not Terminated do
begin
Sleep[100];
end;
// process the file
IsFileInUse
Mã:
function IsFileInUse[const FileName: string]: Boolean;
var
Handle: HFILE;
begin
Handle := CreateFile[PChar[FileName],
GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0];
Result := [Handle = INVALID_HANDLE_VALUE];
if not Result then
CloseHandle[Handle];
end;
Có cách nào tốt hơn và hiệu quả hơn để tránh Sleep
không?
Hỏi ngày 20 tháng 12 năm 2018 lúc 12:02Dec 20, 2018 at 12:02
4
Không, không có API nào có thể được thông báo khi mở tệp trở nên khả thi. Các chương trình giám sát loại hoạt động này [ví dụ: ProcessMonitor] sử dụng trình điều khiển hệ thống tệp [liên kết].
Mặc dù vậy, hãy cân nhắc việc từ bỏ việc mở tệp, vì nó giới thiệu khả năng tệp không có sẵn trở lại ở giữa mở thử và mở thực tế để xử lý.
Đã trả lời ngày 20 tháng 12 năm 2018 lúc 12:46Dec 20, 2018 at 12:46
SERTAC AKYUZSERTAC AKYUZSertac Akyuz
53,7K4 Huy hiệu vàng96 Huy hiệu bạc162 Huy hiệu Đồng4 gold badges96 silver badges162 bronze badges
1
Đồng nghiệp của tôi đã cho tôi thấy một mẹo về cách làm điều này sớm hơn. Những gì tôi đã cố gắng làm là thăm dò một thư mục cho một loạt các tệp và nếu chúng không ở đó tiếp tục bỏ phiếu cho đến khi chúng đến, sau đó xử lý chúng. Vấn đề là trước khi chúng có thể được xử lý, chúng tôi cần chắc chắn rằng việc truyền tệp hoàn tất.
Bí quyết về cách thực hiện việc này là thử và mở tệp sau khi nó đến chế độ ’nối vào chế độ. Điều này sẽ thất bại nếu một quá trình khác đang sử dụng tệp. Vì vậy, những gì chúng ta có thể làm trong trường hợp này sau đó là tiếp tục cố gắng mở nó ở chế độ nối cho đến khi nó thành công và tại thời điểm đó, chúng ta biết rằng không còn khóa trong tệp nữa.
Nghe có vẻ hơi hack nhưng chúng tôi không thể nghĩ ra một cách thanh lịch hơn để làm điều đó.
import os, time def is_locked[filepath]: """Checks if a file is locked by opening it in append mode. If no exception thrown, then the file is not locked. """ locked = None file_object = None if os.path.exists[filepath]: try: print "Trying to open %s." % filepath buffer_size = 8 # Opening file in append mode and read the first 8 characters. file_object = open[filepath, 'a', buffer_size] if file_object: print "%s is not locked." % filepath locked = False except IOError, message: print "File is locked [unable to open in append mode]. %s." % \ message locked = True finally: if file_object: file_object.close[] print "%s closed." % filepath else: print "%s not found." % filepath return locked def wait_for_files[filepaths]: """Checks if the files are ready. For a file to be ready it must exist and can be opened in append mode. """ wait_time = 5 for filepath in filepaths: # If the file doesn't exist, wait wait_time seconds and try again # until it's found. while not os.path.exists[filepath]: print "%s hasn't arrived. Waiting %s seconds." % \ [filepath, wait_time] time.sleep[wait_time] # If the file exists but locked, wait wait_time seconds and check # again until it's no longer locked by another process. while is_locked[filepath]: print "%s is currently in use. Waiting %s seconds." % \ [filepath, wait_time] time.sleep[wait_time] # Test if __name__ == '__main__': files = [r"C:\testfolder\testfile1.txt", r"C:\testfolder\testfile2.txt"] print wait_for_files[files]
Output:
Trying to open C:\testfolder\testfile1.txt. File is locked [unable to open in append mode]. [Errno 13] Permission denied: ‘C:\\testfolder\\testfile1.txt’. C:\testfolder\testfile1.txt is currently in use. Waiting 5 seconds. Trying to open C:\testfolder\testfile1.txt. C:\testfolder\testfile1.txt is not locked. C:\testfolder\testfile1.txt closed. Trying to open C:\testfolder\testfile2.txt. C:\testfolder\testfile2.txt is not locked. C:\testfolder\testfile2.txt closed.