在Windows上,如何打开一个已经打开的文件来写入另一个进程?

我试图打开一个日志文件保持打开另一个进程,并删除前几行。 在Unix上,我只需要做一个os.open('/tmp/file.log', os.O_NONBLOCK) ,这会让我更接近我的目标。

现在我坚持与Windows,我需要以某种方式旋转此日志,而不必结束持有该文件的应用程序。 这甚至有可能吗?

起初,我考虑在应用程序预期日志所在的位置打开一个文件句柄,并将其用作Python中的文件句柄,但是我无法在Windows上find任何方法。

我也想过只是定期移动文件,让应用程序重新创build文件,但是因为它被另一个没有太大作用的进程所使用

也想到O_SHLOCK ,但又是Unix,而不是Windows。 所以我去了mmap这个文件,希望这会让它更加灵活一点,但是这并没有让我感到满意。

 import mmap import contextlib import time with open(r'test.log', 'r+') as f: with contextlib.closing(mmap.mmap(f.fileno(), 0)) as m: while 1: line = m.readline() if len(line) > 0: print line time.sleep(0.5) 

这导致应用程序无法访问文件,因为Python持有它(反之亦然)。

来思考signal.SIGHUP但在Windows中并不存在这么signal.SIGHUP

我卡住了,我已经试过了,Python可以帮我吗,还是需要切换语言?

即使应用程序将文件作为共享对象打开,Python也不能让它们看起来不能相处。

也不是那么坏 :)。 您可以(必须)使用CreateFile打开文件,正如Augusto所指出的那样。 你可以使用标准的ctypes模块。 在问题中使用一个结构作为python ctypes模块的函数参数,你可以看到如何做到这一点。 然后,您必须将C运行时文件描述符与您在上一步中获得的现有操作系统文件句柄相关联。 您可以使用MS C运行时库(CRT)中的_open_osfhandle来执行此操作。 你可以使用ctypes再次调用它; 你可以通过ctypes.cdll.msvcrt._open_osfhandle来访问它。 然后,您必须将Python文件对象与您在上一步中获得的现有C运行时文件描述符相关联。 要在Python 3中执行此操作,只需将文件描述符作为第一个参数传递给内置的open函数即可。 根据文件

文件是字符串或字节对象,提供要打开的文件的路径名(绝对或相对于当前工作目录) 或要打包的文件的整数文件描述符

在Python 2中,你必须使用os.fdopen ; 根据文件,它的任务是

返回一个打开的文件对象连接到文件描述符fd

以上所有内容都不应该被要求做这么简单的事情。 当Windows上的CPython实现开始使用本地Windows API文件而不是通过C运行时库,而不能访问Windows平台的许多功能时,希望它会简单得多。 有关详细信息,请参阅使用本机Windows API问题添加新的io.FileIO

你有任何控制生成日志文件的应用程序? 因为根据该应用程序打开该文件的方式,您实际上不能修改它。

这个链接在这里可能看起来不是主题,但在Windows深处,决定访问其他应用程序的文件是CreateFile函数的dwShareMode参数: http : //msdn.microsoft.com/en-us/library/windows/desktop /aa363858%28v=vs.85%29.aspx

应用程序应启用FILE_SHARE_WRITEFILE_SHARE_DELETE ,并且每次写入文件时都应刷新和更新文件位置。 查看open()的Python 文档 ,没有这样详细的参数。