IOException异常:因为它正在被其他进程无法访问文件“文件路径”的过程 [英] IOException: The process cannot access the file 'file path' because it is being used by another process

查看:1319
本文介绍了IOException异常:因为它正在被其他进程无法访问文件“文件路径”的过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些code和在执行时,它抛出一个 IOException异常,说的该进程无法访问文件文件名,因为它是正由另一个进程的。

I have some code and when it executes, it throws a IOException, saying "The process cannot access the file 'filename' because it is being used by another process".

这是什么意思,和我能做些什么呢?

What does this mean, and what can I do about it?

当然,这不是一个真正的问题;我发现有很多问题,在这里等都是与此相关的错误让一个一般性的指导(像这样的的NullReferenceException 和的 IndexOutOfRangeException 的)可能是有用的。

Of course this is not a real question; I found many questions here on SO are related to this error so a general guidance (like this one for NullReferenceException and IndexOutOfRangeException) may be useful.

答案是一个社区的wiki可以随意编辑和改善它与常见的情况和建议。

Answer is a community wiki so feel free to edit and improve it with more common scenarios and suggestions.

推荐答案

错误信息是pretty的清楚:你要访问一个文件,它是不可访问,因为另一个进程(甚至是同一过程)是做一些与它(并没有让任何共享)。

What is the cause?

Error message is pretty clear: you're trying to access a file and it's not accessible because another process (or even the same process) is doing something with it (and it didn't allow any sharing).

这可能是pretty的容易解决(或pretty的很难理解),这取决于您的具体方案。让我们来看看一些。

It may be pretty easy to solve (or pretty hard to understand), depending on your specific scenario. Let's see some.

您的过程是唯一一个访问该文件
你确定的的过程是自己的过程。如果你知道你打开你的程序的其他部分的文件,那么首先你必须在每次使用后请检查你正确地关闭文件句柄。这里code这个错误的一个例子:

Your process is the only one to access that file
You're sure the other process is your own process. If you know you open that file in another part of your program then first of all you have to check you properly close file handle after each use. Here an example of code with this bug:

var stream = new FileStream(path, FileAccess.Read);
var reader = new StreamReader(stream);
// Read data from this file, when I'm done I don't need it any more
File.Delete(path); // IOException: file is in use

好在的FileStream 工具的IDisposable 所以很容易将保鲜膜一个<$ C $内的所有code C>使用语句:

Fortunately FileStream implements IDisposable so it's easy to wrap all your code inside a using statement:

using (var stream = File.Open("myfile.txt", FileMode.Open)) {
    // Use stream
}

// Here stream is not accessible and it has been closed (also if
// an exception is thrown and stack unrolled

此模式也将确保文件不会被留在例外情况下,开放式(也可能是原因文件正在使用中:出事了,没有人关闭了它,看到的这个帖子一个例子)。

This pattern will also ensure file won't be left open in case of exceptions (it may be the reason file is in use: something went wrong and no one closed it, see this post for an example).

如果一切似乎罚款(你确定你总是关闭每一个文件打开,即使在例外的),你有多个工作线程,那么你有两个选择:你返工code序列化文件访问(不总是可行的,而不是一直想)或应用的重试模式的。这是一个pretty的常见模式I / O操作:尝试做一些事情,在出现错误时,你等着,然后再试一次(你问过自己为什么,例如,Windows Shell中需要一些时间来通知你,文件在使用中,不能删除?)。在C#这是pretty的容易实现(参见有关磁盘I / O ,的networking 数据库访问)。

If everything seems fine (you're sure you always close every file you open, even in case of exceptions) and you have multiple working threads then you have two options: rework your code to serialize file access (not always doable and not always wanted) or apply a retry pattern. It's a pretty common pattern for I/O operations: you try to do something and in case of error you wait and try again (did you ask yourself why, for example, Windows Shell takes some time to inform you that file is in use and cannot be deleted?). In C# it's pretty easy to implement (see also better examples about disk I/O, networking and database access).

private const int NumberOfRetries = 3;
private const int DelayOnRetry = 1000;

for (int i=1; i <= NumberOfRetries; ++i) {
    try {
        // Do stuff with file
        break; // When done we can break loop
    }
    catch (IoException e) {
        // You may check error code to filter some exceptions, not every error
        // can be recovered.
        if (i == NumberOfRetries) // Last one, (re)throw exception and exit
            throw;

        Thread.Sleep(DelayOnRetry);
    }
}

请注意一个常见的​​错误,我们可以看到很多时候在计算器:

Please note a common error we can see very often on StackOverflow:

var stream = File.Open(path, FileOpen.Read);
var content = File.ReadAllText(path);

在这种情况下, ReadAllText()将失败,因为文件正在使用中( File.open方法()的前行)。要打开文件之前,他们不仅没有必要,而且是错误的。同样适用于所有的文件函数不返回的处理的你正在使用的文件: File.ReadAllText () File.WriteAllText() File.ReadAllLines() File.WriteAllLines()和其他人(如 File.AppendAllXyz()函数)将所有打开和关闭文件本身。

In this case ReadAllText() will fail because file is in use (File.Open() in the line before). To open the file before them is not only unnecessary but also wrong. Same applies to all File functions that doesn't return an handle to file you're working with: File.ReadAllText(), File.WriteAllText(), File.ReadAllLines(), File.WriteAllLines() and others (like File.AppendAllXyz() functions) will all open and close file by themselves.

您的过程是不是唯一一个访问该文件
如果你的过程是不是唯一一个访问该文件,那么交互也很难。 A 重试模式的帮助(如果文件不应该由任何人开放,但它是那么你需要像的Process Explorer的工具来检查的 <谁/ em>的是做的什么的)。

Your process is not the only one to access that file
If your process is not the only one to access that file then interaction can be harder. A retry pattern will help (if file shouldn't be open by anyone else but it is then you need an utility like Process Explorer to check who is doing what).

在应用始终使用的使用的语句来打开文件。由于在previous段表示,将积极帮助您避免许多常见错误(见这个帖子一个例子关于如何不使用它)。

When applicable always use using statement to open files. As said in previous paragraph it'll actively help you to avoid many common errors (see this post for an example about how to don't use it).

如果可能的话,以决定谁拥有访问特定的文件,并通过集中几家知名的方法访问。如果,例如,你有一个数据文件,你的程序读取和写入,那么你应该框中的所有I / O $ C $里面一个C类。这会让调试更加容易(因为你总是可以把一个断点那里,看看谁在做什么),而且这将是一个同步点(如果需要)的多址。

If possible try to decide who owns access to a specific file and centralize access through few well-known methods. If, for example, you have a data file where your program read and write then you should box all I/O code inside a single class. It'll make debug easier (because you can always put a breakpoint there and see who is doing what) and also it'll be a synchronization point (if required) for multiple access.

不要忘了I / O操作总是失败,一个常见的​​例子是这样的:

Don't forget I/O operations can always fail, a common example is this:

if (File.Exists(path))
    File.Delete(path);

如果有人的后删除文件File.Exists()但在此之前 File.Delete()然后它会抛出一个 IOException异常在一个地方,你可能会错误地感到安全。

If someone delete file after File.Exists() but before File.Delete() then it'll throw an IOException in a place you may wrongly feel safe.

只要有可能适用的重试模式的,如果你使用 FileSystemWatcher的考虑推迟行动(因为你会得到通知,但应用程序可能会仍与该文件)专门的工作。

Whenever it's possible apply retry pattern and if you're using FileSystemWatcher consider to postpone action (because you'll get notified but application may still be working exclusively with that file).

高级场景
这并不总是那么容易,所以你可能需要与他人分享的访问。如果,例如,你正在阅读从开始写作到最后你至少有两个选项。

Advanced scenarios
It's not always so easy so you may need to share access with someone else. If, for example, you're reading from beginning and writing to the end you have at least two options.

1)共享同一个的FileStream 适当的同步功能(因为它不是线程安全的)。请参见这个岗位为例。

1) share same FileStream with proper synchronization functions (because it is not thread-safe). See this and this posts for an example.

2)使用文件共享枚举指示操作系统您允许其他进程(或者你自己的工作的其他部分)同时访问同一个文件。

2) use FileShare enumeration to instruct OS you allow other processes (or other parts of your own process) to access same file concurrently.

using (var stream = File.Open(path, FileMode.Open, FileAccess.Write, FileShare.Read))
{
}

在这个例子中,我展示了如何打开文件进行写入和共享阅读,请注意,当读写重叠的结果是不确定的,数据可能是无效的。这是读书时的情况,必须进行处理。还要注意的是这并没有获得线程安全的,然后这个对象不能被多个线程共享,除非获得以某种方式同步(见previous链接) 。其他共享选项是可用的,她们向更复杂的情况,请参阅的 MSDN 了解详细信息。

In this example I shown how to open file for writing and share for reading, please note that when read and write overlaps result is undefined and data may be invalid. It's a situation must be handled when reading. Also note that this doesn't make access to stream thread safe then this object can't be shared with multiple threads unless access is synchronized somehow (see previous links). Other sharing options are available and they open to more complex scenarios so please refer to MSDN for details.

在一般的 N 的进程可以从同一个文件中读取在一起,但只有一个应该写,在受控制的情况下,你甚至可以实现并行的著作,但是这并不能在这里面几个文本段落一概而论的回答。

In general N processes can read from same file all together but only one should write, in a controlled scenario you may even enable concurrent writings but this can't be generalized in few text paragraphs inside this answer.

这篇关于IOException异常:因为它正在被其他进程无法访问文件“文件路径”的过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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