在Windows上,如何打开一个已经打开的文件来写入另一个进程? [英] On Windows, how to open for writing a file already opened for writing by another process?

查看:226
本文介绍了在Windows上,如何打开一个已经打开的文件来写入另一个进程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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



起初,我考虑在应用程序期望日志的位置打开一个文件句柄,并将其作为一个文件句柄在Python中,但我无法找到任何方式在Windows上做这件事。



我也想定期移动文件,让应用程序重新创建文件,但因为它被另一个进程使用,所以没有什么好处。

想到 O_SHLOCK code>,但是再次,这是Unix而不是Windows。
所以我去了mmap的文件,并希望它会使它更灵活一点,但是这没有带来我的。

 输入mmap 
输入contextlib
输入时间

打开(r'test.log','r +')作为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持有它(反之亦然)。
$ b 来到 signal.SIGHUP code>但在Windows中不存在,所以回到原点。



我卡住了,我已经试过了,Python可以帮助我在这里还是我需要切换我的语言?
解决方案

即使应用程序打开文件作为一个共享对象Python不能
,所以他们不能相处的样子。


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


file 是一个字符串或字节对象,给出路径名(绝对或相对于当前工作目录)到
被打开或被包装文件的整数文件描述符


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


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


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

I'm trying to open a logfile which is kept open by another process and remove the first few lines. On Unix I'd simply do a os.open('/tmp/file.log', os.O_NONBLOCK) and that would get me closer to my goal.

Now i'm stuck with Windows and I need to rotate this log somehow without ending the application holding the file. Is this even possible?

At first I considered opening a file handle on the location where the application expected the log to be and just act as a pipe into a file-handle in Python but I couldn't find any way of doing that either on Windows.

I also thought of just moving the file on a regular basis and letting the application recreate the file but since it's being used by another process that doesn't do much good.

Thought of O_SHLOCK as well but then again, that's Unix and not Windows. So I went for mmap the file and hope that it would make it a bit more flexible but that led me nowhere.

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)

This results in that the application can't access the file because Python is holding it (and vice versa).

Came to think of signal.SIGHUP but that doesn't exist in Windows either so back to square one.

I'm stuck and I've tried it all, can Python help me here or do I need to switch my language?

解决方案

Even if the application opens the file as a shared object Python can't so they can't get along by the looks of it.

It's not so bad :). You can (have to) open a file using CreateFile as pointed out by Augusto. You can use standard ctypes module for this. In the question Using a struct as a function argument with the python ctypes module you can see how to do it. Then you have to associate a C run-time file descriptor with an existing operating-system file handle you obtained in the previous step. You can use _open_osfhandle from the MS C run-time library (CRT) to do this. You can call it once again using ctypes; you can access it as ctypes.cdll.msvcrt._open_osfhandle. Then you have to associate Python file object with an existing C run-time file descriptor you obtained in the previous step. To do this in Python 3 you simply pass file descriptor as the first argument to the built-in open function. According to docs

file is either a string or bytes object giving the pathname (absolute or relative to the current working directory) of the file to be opened or an integer file descriptor of the file to be wrapped.

In Python 2 you have to use os.fdopen; its task, according to docs, is to

Return an open file object connected to the file descriptor fd

All of the above should not be required to do such a simple thing. There's hope it will be much simpler when CPython's implementation on Windows starts using native Windows API for files instead of going through C run-time library which does not give access to many features of Windows platform. See Add new io.FileIO using the native Windows API issue for details.

这篇关于在Windows上,如何打开一个已经打开的文件来写入另一个进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆