在不阻止其他进程写入的情况下读取Windows文件

2 投票
2 回答
1155 浏览
提问于 2025-04-17 14:16

我有一个文件想要读取。但是这个文件可能随时会被其他程序覆盖。我不想阻止这个写入的过程。我可以接受读取到的数据可能会损坏,但我希望我的读取操作不会影响到写入程序的行为。

写入这个文件的程序是一个在服务器本地运行的Delphi程序。它使用fmCreate来打开文件。fmCreate会尝试独占打开文件,如果文件上有其他的句柄,它就会失败。

我则是通过一个Python脚本从网络上远程读取这个文件。

我想知道有没有解决办法,不管它是否被Python或Delphi支持。我想知道在Windows系统下,是否有办法在不修改写入程序的情况下实现这个目标。

补充说明:我想重申一下,这不是重复的问题。之前的问题是想要获取一个正在被写入的文件的读取权限。而我希望的是,写入程序能够访问我已经打开用于读取的文件。这是两个不同的问题(虽然我担心答案会是类似的,可能无法实现)。

2 个回答

0

你可以设置一个过滤驱动程序,它可以有两种功能:第一,当文件被打开时,可以修改一些标志;第二,当数据写入文件时,它可以捕捉这些数据,并把数据的副本保存到其他地方。

这种方法比评论中提到的卷影复制服务要轻便和高效得多,不过它需要一个过滤驱动程序。市场上有几种这样的驱动程序(也就是说,这些是包含驱动程序的产品,允许你在用户模式下编写业务逻辑),但它们价格不便宜,可能对你来说有点过于复杂。如果你只是想私下使用,可以私下联系我,获取我们CallbackFilter的许可证。

更新:如果你想让写入者打开一个已经被打开的文件,那么在文件打开时修改标志的过滤器就是你唯一的选择。

2

我觉得这里真正的答案是使用机会锁。这样,你可以打开文件进行读取,同时告诉操作系统,如果其他程序想要访问这个文件,你希望能收到通知。简单来说,你可以随意使用这个文件,但如果有人需要它,你就可以让开。这避免了如果你只是“正常”打开文件时,其他程序可能会遇到的共享/访问冲突问题。

这里有一篇关于机会锁的MSDN文章。Raymond Chen也写了一篇博客,里面有示例代码:使用机会锁在其他人需要文件时让开

关键是要调用DeviceIoControl函数,使用FSCTL_REQUEST_OPLOCK标志,并传入你之前通过调用CreateEvent创建的事件句柄。

在Delphi中使用这个应该很简单,因为它支持调用Windows API函数。我对Python就不太确定了。不过,根据问题中的安排,应该不需要修改Python代码。只要让你的Delphi代码在打开文件时使用机会锁,当Python脚本需要文件时,就让它让开。

而且,这比过滤驱动程序或卷影复制服务要简单得多,负担也轻。

撰写回答