流读取器进程无法访问文件,因为该文件正在被另一个进程使用。

6

我的应用程序解析日志文件,但在尝试解析当天的文件时,我会收到一个错误,指出该文件正在被另一个进程使用。这个日志文件目前正在写入,并且可以通过记事本访问,但不能通过我的应用程序访问。

当前代码:

Stream stream = new FileStream(fileToRead, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(stream);

我也尝试了这个方法,但没有成功:
Stream stream = new FileStream(fileToRead, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

如何修改代码以读取正在被其他进程使用的文件。复制日志文件不是解决方案,因为日志文件大小和应用程序性能问题。


1
请查看此链接:https://dev59.com/iEbRa4cB1Zd3GeqP4-1m - LostInComputer
我尝试了:Stream stream = new FileStream(fileToRead, FileMode.Open, FileAccess.Read, FileShare.Read); 但是没有成功。 - SlopTonio
如果文件正在被另一个进程写入,则您需要指定(至少)FileShare.WriteFileShare 表示您希望其他用户对文件进行的操作。当然,如果其他进程在打开文件时没有指定(相当于)FileShare.Read,这仍将失败。 - Damien_The_Unbeliever
我已经尝试了FileShare.Read、FileShare.Write和FileShare.ReadWrite,但都没有成功。还有其他建议吗? - SlopTonio
1
你说记事本可以正常打开文件,但是你的代码却不能。使用进程监视器来检查你的代码和记事本打开文件的不同方式,并将这些信息添加到你的问题中(如果你不知道如何修复你的代码以使其像记事本一样工作)。 - Damien_The_Unbeliever
显示剩余2条评论
3个回答

10

我们可以使用不同的签名打开文件流以便其他进程能够读写:

Stream stream = new FileStream(fileToRead, FileMode.Open, FileAccess.Read,
                        FileShare.ReadWrite);
或者
Stream stream = File.Open(fileToRead, FileMode.Open, FileAccess.Read,
                        FileShare.ReadWrite);

FileShare选项确定当该进程打开同一文件时,其他进程如何访问相同的文件。

您的第一个代码块将默认为FileShare.None

Stream stream = new FileStream(fileToRead, FileMode.Open, FileAccess.Read);

当文件处于打开状态时,此操作将失败,因为它试图获取对该文件的独占访问权。

然而,您需要在日志编写器中进行此操作,以便您的日志读取器可以具有读取访问权限。

最后,尝试以管理员身份运行您的日志读取器,因为可能存在操作系统权限问题,这些问题在使用“记事本打开”时不明显。


我已经尝试了FileShare.Read、FileShare.Write和FileShare.ReadWrite,但都没有成功。还有其他建议吗? - SlopTonio
如上所述,你需要日志写入程序使用FileShare.Read来打开文件流;检查日志写入程序的代码并确定它在创建新的日志文件时是否使用了FileShare.Read - Kevin Hogg
我的程序没有写/创建这个日志文件,我无法访问它。它是由我们公司的一个网站在写入。我无法访问那段代码。 - SlopTonio
1
注意一个bug:我一直在遇到同样的错误;经过长时间的研究,原因是后续以较少FileShare访问权限打开文件会导致异常。*(在我的情况下,文件首先作为FileStream使用FileShare.ReadWrite打开,然后再次使用using (var stream = File.OpenRead(file))打开,它没有这个选项,但很可能将其设置为None)* - Hi-Angel

1

我曾遇到类似的问题,通过设置文件属性解决了该问题。

File.SetAttributes(outputDirectory + fileName + ".txt", FileAttributes.Normal);

这是在文件创建后完成的。问题与操作系统如何管理被多个进程访问的文件有关。在我的情况下,我删除了该文件(你并不总是被允许这样做,因为你会看到你正在看到的错误)。唯一真正解决这个问题的方法是追踪正在访问该文件的进程并停止它们。我解决这个问题最简单的方法是重新启动我的电脑,但如果你正在一个服务器上工作,那就不可行了。
我没有进行大量测试,但如果你想让这个程序被多个进程使用,也许给文件读取属性和/或属性可能是个好主意。
File.SetAttributes(outputDirectory + fileName + ".txt", FileAttributes.ReadOnly);

祝好运 - 希望这篇文章能对其他人有所帮助(因为这已经是一年前的事情了!)。


1

这里是一个代码片段

问题在于当另一个应用程序首先打开文件并且文件共享为只读(FileShare.Read)时,您肯定无法对文件进行写入操作,但仍然可以读取。或者文件共享为只写(FileShare.Write),您无法读取文件,但仍然可以向其写入。

 using (FileStream file = new FileStream("You File Name here", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
        {
            using (StreamReader sr = new (StreamReader (file))
            {
        //Do your codes here     
            }
        }

我尝试了上面的代码,但是我使用的是StreamReader而不是StreamWriter,因为我正在尝试读取文件而不是写入它。但我仍然无法访问该文件。 - SlopTonio
@SlopTonio,看看我的更新。 - Jade
1
正如我之前所评论的,我尝试过了,但仍然无法访问该文件。这很奇怪,因为记事本可以打开日志文件,但我的应用程序却不能。 - SlopTonio

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