工作所需,需要写一个程序读取一直在更新的log文件(Wintrace.log),发现里面的error。 同时有另外的程序写入log文件,在log文件的大小达到15626kb时改名字(wintrace-001.log),并且重新生成一个空的log文件(Wintrace.log)。
第一种方法:直接打开原文件Wintrace.log。
fo = open("C:\Winusr\Wintrace.log", "rb")
发现我的程序不会阻止其他的程序写入,但是会阻止log file在满的时候改名字。导致log file丢失的问题。因为如果无法重命名,他就只能在现在的log file清除重新写入,历史文件将不存在。
第二种方法:实时复制原文件。读取复制的文件。
old_size = os.path.getsize("C:\Winusr\Wintrace.log")
while os.path.getsize("C:\Winusr\Wintrace.log")>= old_size:
shutil.copy("C:\Winusr\Wintrace.log", "C:\Winusr\wintrace1.log")
fo = open("C:\Winusr\wintrace1.log", "rb")
发现还是不可以。虽然copy的操作看起来没有影响到原文件,但是copy操作是逐字节copy,实际上已经打开了原文件。所以还是行不通,无法重命名。
第三种方法:使用popen copy原文件。
os.chdir("C:\Winusr")
original_path = paths["wintrace"][10:]
if original_path == "Wintrace.log":
f = os.popen('copy Wintrace.log wintrace1.log')
f.close()
fo = open("C:\Winusr\wintrace1.log", "rb")
网上说是打开了一个子程序,不会影响主程序。但是我不懂。试过了之后发现可以重命名。但是目前好像又发现一个问题,还不确定。就是在log file快要到达15626KB时,主程序出现了报错?
各位大佬有什么建议吗?
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1/12/2021
终于找到了一个目前看来还没什么问题的解决方案。
早知道第一次就用这个办法了,也不至于搞死其他程序。。。
用的是win32file。
程序如下:
import win32file
file_handle = win32file.CreateFile(paths["wintrace"], win32file.GENERIC_READ,
win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE,
None, win32file.OPEN_EXISTING, win32file.FILE_ATTRIBUTE_NORMAL, None)
win32file.SetFilePointer(file_handle, 1, start_point)
result, fo = win32file.ReadFile(file_handle, 100000000)
for line in fo.splitlines():
line = str(line.decode('ISO-8859-1'))
print(line)
start_point = win32file.FILE_END
win32file.CloseHandle(file_handle)
要注意的问题:
1. 安装win32file需要安装pywin32而不是直接安装win32file(对我来说)。直接“pip install win32file”会报错。“pip install pywin32” 则可以安装成功。
2. win32file.CreateFile 返回的是句柄而不是文件类型,所以不可以直接用open打开。打开它需要用win32file.Readfile(). 如果需要逐行读取,则需要用到splitlines.
3. 关于文件指针,需要用
win32file.SetFilePointer(file_handle, 1, start_point)
start_point = win32file.FILE_END(用来获取文件最后的位置)
4. 记得用完之后关闭句柄:
win32file.CloseHandle(file_handle)