如何从正在使用的文件中读取

Posted

技术标签:

【中文标题】如何从正在使用的文件中读取【英文标题】:How to read from a file that is in use 【发布时间】:2014-11-14 22:14:47 【问题描述】:

我想进入一个文件,但每当我尝试打开它时,我都会收到消息“该进程无法访问该文件,因为它正被另一个进程使用”。

嗯,我想进去!那么,我该怎么做呢?

我一直在集思广益尝试几种方法,我希望在其他方法上获得一些意见,或者如果我的想法由于某种对我来说并不明显的原因而行不通。

想法 1 文件夹知道文件在哪里,只是不会打开它。如果我创建一个程序来读取文件的内存地址,复制它,然后在其他地方重建它怎么办?我不确定这是否有希望,因为它依赖于问题所在的文件。 想法 2 我的进程如何知道另一个进程正在使用该文件?如果它正在检查所有其他进程,也许我还可以找出哪个进程正在使用该文件并暂停或结束它。

这些想法中的任何一个都可能需要我几周的时间。有没有人更有创意,能想出另一种方式;还是知识渊博并消除不切实际的想法?

【问题讨论】:

使用文件的副本? “该操作无法完成,因为该文件已在系统中打开”,该文件据说正在某处使用,我想解决这个问题 openfiles command openfiles 命令看起来很有希望,我将把它作为最后的手段。如果可能,我想避免断开连接,因为它是一个系统进程,我不确定会产生什么影响 你应该重新审视为什么你需要这样做。您可能应该改用数据库吗? 【参考方案1】:

在 Windows 中,允许应用程序获取独占的locks on files。当进程opens the file 时,您指定的一件事是who else can access it while your process does(这些是 .NET 方法,但其他语言中存在等效方法)。例如,Excel 因在打开文件时获得排他锁而臭名昭著。绕过它的方法通常是to find the offending process and kill it 来打破锁定。 Unlocker 是我最熟悉的用于完成此任务的应用程序。但是,如果该进程是系统进程,您可能无法杀死它。您必须重新启动才能重置锁定。

直接从另一个进程的内存中读取不太可能是可靠的。应用程序可能没有内存副本,可能没有完整的内存副本,可能没有一致的内存副本,并且可能没有与磁盘上的内容匹配的内存副本(如果他们正在编辑文档,例如)。

您的进程知道该文件已被锁定,因为当它试图打开该文件时,它会通过请求操作系统访问该文件来做到这一点。操作系统回应说,“请求被拒绝。另一个进程打开并锁定了这个文件。”操作系统不会告诉您的进程哪个进程打开了文件,因为尝试打开文件不包括询问谁已经打开了文件。您的流程必须提出正确的问题才能得到您正在寻找的答案。

【讨论】:

“直接从另一个进程的内存中读取不太可能是可靠的”——Windows 甚至会让你这样做吗? afaik,操作系统为每个进程提供了自己的虚拟内存空间。 好消息,因为是操作系统说不,如果我直接读取它的字节(不打开它)可能不会有问题 @RedAlert 是的,请参阅 ReadProcessMemory:msdn.microsoft.com/en-us/library/windows/desktop/… @RedAlert Windows 会让你这样做。这就是进程转储和在线调试器的工作方式。数据执行保护的存在不是为了揭示伪劣编码——它是作为副作用来做到的——它的存在是为了防止第三方程序更改程序标记为数据的内容,并使其更难控制系统直接写入内存。【参考方案2】:

Windows 让您在打开文件时指定共享模式。共享模式可能会阻止文件在您打开时被读取、写入或删除。如果您想允许同时读取访问,您应该在调用CreateFile (http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx) 时将FILE_SHARE_READ 包含在dwShareMode 参数中。

换句话说,如果要启用对打开文件的并发访问,则必须首先修改文件的打开方式。

C 和 Java 中的可移植标准库不提供在打开文件时设置共享模式的方法,但它们在 Windows 上的通常实现将共享模式设置为 READ+WRITE。

【讨论】:

这不是权限问题(我有理由确定),该文件已被系统使用,因此它不会让我打开另一个版本。 这不是关于权限,而是关于独占访问,这是一种不同的安全功能。如果您找到一种以操作系统不允许的方式访问文件的方法,您应该向操作系统提交错误。

以上是关于如何从正在使用的文件中读取的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Powershell 从 csv 文件中仅读取一列

如何使用 VBScript 从文本文件中读取?

如何从OpenCV的目录中按顺序读取文件?

如何从 thymeleaf 中的属性文件中读取值

使用 AudioKit 从 MIDI 文件中读取音符

如何使用 Parquet.net 从 Parquet 文件中仅读取列的一部分?