[英]Windows: iterate on a file in python using Win32API
我正在嘗試使用Win32Api在Python中讀取文件,以便能夠在不將其鎖定在Windows系統上的情況下打開文件。
我已經能夠打開文件甚至從文件中讀取文件,但是當我嘗試實現迭代器協議時,會收到一條我無法理解的錯誤消息。
這是重現問題的示例腳本
#!/usr/bin/env python
import os
class FileTail(object):
def __init__(self, file):
self.open(file)
def open(self, file):
"""Open the file to tail and initialize our state."""
fh = None
import win32file
import msvcrt
handle = win32file.CreateFile(file,
win32file.GENERIC_READ,
win32file.FILE_SHARE_DELETE |
win32file.FILE_SHARE_READ |
win32file.FILE_SHARE_WRITE,
None,
win32file.OPEN_EXISTING,
0,
None)
file_descriptor = msvcrt.open_osfhandle(
handle, os.O_TEXT | os.O_RDONLY)
fh = open(file_descriptor, encoding='utf-8',
errors='ignore', newline="\n")
self.reopen_check = "time"
self.fh = fh
self.file = file
# Uncommenting this code demonstrate that there's no problem reading the file!!!!
# -------------------------------------------------------------------------------
# line = None
# self.wait_count = 0
# while not line:
# line = self.fh.readline()
def __iter__(self):
return self
def __next__(self):
line = None
self.wait_count = 0
while not line:
line = self.fh.readline()
return line
# ##############################
# ENTRY POINT
# ##############################
if __name__ == "__main__":
my_file = FileTail('C:\LOGS\DANNI.WEB\PROVA.LOG')
for line in my_file:
print(line)
現在,如果您嘗試執行此腳本,您將收到以下錯誤消息:
Traceback (most recent call last):
File "C:\Users\me\Desktop\prova.py", line 63, in <module>
for line in my_file:
File "C:\Users\me\Desktop\prova.py", line 53, in __next__
line = self.fh.readline()
OSError: [Errno 9] Bad file descriptor
如果我取消注釋“打開”方法中的注釋代碼,則可以讀取整個文件,因此我認為問題不在於使用win32 api打開文件...所以...我失蹤?
為什么使用迭代器協議會收到錯誤消息? 它是與線程相關的問題嗎? 我該如何解決?
我知道可能會有一千種解決方法,但我想了解為什么此代碼無法正常工作...
謝謝大家為您提供的幫助,對不起我的英語不好... :(
戴夫
問題在於,在函數open
返回之后,對象handle
和file_descriptor
可能會被垃圾回收。 當您調用__next__
,對象可能已被釋放,從而引發OSError: [Errno 9] Bad file descriptor
。 這就是為什么當您在open函數本身中讀取文件時它可以工作的原因,因為那里的對象仍然存在。
為了解決這個問題,只需將對象存儲為實例屬性,以便至少有一個對它們的引用。
def open(...)
...
self.handle = CreateFile(...)
...
self.file_descriptor = msvcrt.open_osfhandle(self.handle, ...)
...
self.fh = open(self.file_descriptor, ...)
...
僅存儲其中之一可能就足夠了,但是我不確定是哪一個。 保存兩者都是保存的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.