读取被其他进程使用的文件

74

我正在监控一个由服务器程序写入的文本文件。每次文件变化时,内容将输出到我的程序窗口中。

问题是我不能使用 Streamreader 读取该文件,因为它正在被其他进程使用。设置 Filestream 并使用 ReadWrite 也无济于事,因为我无法控制使用该文件的进程。

我可以在记事本中打开该文件。这个服务器正在使用它,但一定有办法访问它。

有什么好的解决方法吗?

我应该采取以下步骤吗?

  1. 监视该文件
  2. 在文件更改时创建临时副本
  3. 读取临时副本
  4. 删除临时副本

每当服务器更改文件时,我需要获取文件中的文本。

2个回答

160

如果记事本可以读取该文件,那么您也可以读取它,显然该程序没有对文件进行读取锁定。您遇到的问题在于StreamReader将使用FileShare.Read打开该文件,这会拒绝写入访问权限。 这是无法工作的,因为其他程序已经获得了写入访问权限。

您需要像这样创建StreamReader:

using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var sr = new StreamReader(fs, Encoding.Default)) {
    // read the stream
    //...
}

在这里猜测编码。你必须小心处理这种代码,因为其他程序正在积极地向该文件写入。您不会得到非常可靠的文件结束标志,很可能只获取到部分最后一行。特别是当您继续读取文件以尝试获取程序附加的任何内容时,这会非常麻烦。


3
谢谢...我没有意识到在这种情况下使用FileShare.Read是不正确的。 - Marcel Popescu
7
使用FileShare.ReadWrite | FileShare.Delete,你可以访问更多数量的文件。当FileShare.ReadWrite不足时,值得一试。 - Adassko
@Adassko 或者当 FileShare.Read 不足以满足需求时,就像在我的情况下一样,我正在使用相同类型的代码,并且必须切换到 FileShare.ReadWrite 才能使其正常工作。 - vapcguy
@Adassko,感谢您的评论,这对我解决了另一个问题。使用EPPlus(一种.NET Excel文件读写器),我确实需要使用“FileShare.ReadWrite | FileShare.Delete”来读取打开的Excel文件,否则我会遇到错误并无法读取该文件。这个方法解决了我的问题,非常感谢! - DotNET Afficionado

19

使用

File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
只要另一个应用程序没有对文件进行独占锁定,这个方法就可以运行。

谢谢。这个能和StreamReader连用吗?像这样:File.Open(path, FileMode.Read, FileAccess.Read, FileShare.ReadWrite); StreamReader reader = new StreamReader(path); - Christoffer
@Tophe:当然可以。如果我没记错的话,StreamReader构造函数也可以直接传递这些参数。 - SLaks
那会是什么样子呢?如果我将FileMode.Open,FileAccess.Read和FileShare.ReadWrite作为参数放入Streamreader中,它就不起作用。 它说只需要某些编码参数。 - Christoffer
然后我记错了,抱歉。 - SLaks
2
FileMode.Read 不存在。 - SandRock

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接