如何最好地等待文件锁释放

发布于 2024-07-15 08:23:13 字数 228 浏览 5 评论 0原文

我有一个应用程序,有时需要读取正在写入的文件并因此被锁定。 正如我从其他 问题 中了解到的那样,我应该捕获 IOException 并重试直到我能阅读。

但我的问题是我如何确定文件已被锁定并且它不是另一个 IOExcetpion 发生。

I have an application where i sometimes need to read from file being written to and as a result being locked. As I have understood from other questions i should catch the IOException and retry until i can read.

But my question is how do i know for certain that the file is locked and that it is not another IOExcetpion that occurs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

椒妓 2024-07-22 08:23:13

当您在 .NET 中打开文件进行读取时,它会在某个时刻尝试使用 CreateFile API 函数,用于设置错误代码 可用于查看失败的原因:

const int ERROR_SHARING_VIOLATION = 32;
try
{
    using (var stream = new FileStream("test.dat", FileMode.Open, FileAccess.Read, FileShare.Read))
    {
    }
}
catch (IOException ex)
{
    if (Marshal.GetLastWin32Error() == ERROR_SHARING_VIOLATION)
    {
        Console.WriteLine("The process cannot access the file because it is being used by another process.");
    }
}

When you open a file for reading in .NET it will at some point try to create a file handle using the CreateFile API function which sets the error code which can be used to see why it failed:

const int ERROR_SHARING_VIOLATION = 32;
try
{
    using (var stream = new FileStream("test.dat", FileMode.Open, FileAccess.Read, FileShare.Read))
    {
    }
}
catch (IOException ex)
{
    if (Marshal.GetLastWin32Error() == ERROR_SHARING_VIOLATION)
    {
        Console.WriteLine("The process cannot access the file because it is being used by another process.");
    }
}
苦笑流年记忆 2024-07-22 08:23:13

Google 论坛上有一个有用的讨论< /a> 你真的应该读一下。 其中一个选项与darin 的接近; 但是,为了保证获得正确的 win32 错误,您确实应该自己调用 win32 OpenFile() API(否则,您真的不知道正在检索哪个错误)。

另一种方法是解析错误消息:如果您的应用程序在另一种语言版本上运行,则解析将会失败。

第三种选择是通过反射侵入异常类以找出实际的 HRESULT。

所有替代方案都没有那么有吸引力:恕我直言,IOException 层次结构将受益于更多的子类。

There's a useful discussion on google groups which you really should read. One of the options is close to darin's; however, to guarantee you get the right win32 error, you really should call the win32 OpenFile() API yourself (otherwise, you really don't know which error you are retrieving).

Another is to parse the error message: that will fail if your application is run on another language version.

A third option is to hack inside the exception class with reflection to fish out the actual HRESULT.

None of the alternatives are really that attractive: the IOException hierarchy would benefit from a few more subclasses IMHO.

习ぎ惯性依靠 2024-07-22 08:23:13

要读取数据,您可以执行以下操作:

使用 (FileStream fs = new
文件流(文件名,文件模式.打开,
文件访问. 读取、文件共享. 读写 |
文件共享.删除)) { .... }

并保存到文件中:

使用 (FileStream fs = new
FileStream(文件名, FileMode.Append,
文件访问.写入、文件共享.读取 |
文件共享.删除)) { ... }

构造函数末尾的标志描述了其他进程可以对该文件执行的操作。 当然,如果您同时控制写入和读取,那就没问题了……

To read data you can do:

using (FileStream fs = new
FileStream(fileName, FileMode.Open,
FileAccess.Read, FileShare.ReadWrite |
FileShare.Delete)) { .... }

and to save into file:

using (FileStream fs = new
FileStream(fileName, FileMode.Append,
FileAccess.Write, FileShare.Read |
FileShare.Delete)) { ... }

Flags at the end of constructors describes what other process can do with the file. It is fine, of course, if you control both write and read...

半窗疏影 2024-07-22 08:23:13

您可以打开它(如 bezieur 所描述),然后尝试锁定部分(或整个文件):
http://www.java2s.com/Code/VB/File-目录/Lockandunlockafile.htm

You may open it (as described by bezieur) then try to lock sections (or whole file) :
http://www.java2s.com/Code/VB/File-Directory/Lockandunlockafile.htm

⊕婉儿 2024-07-22 08:23:13

您的意思是您正在读取和写入文件吗? 或者外部应用程序正在写入它。

如果您正在执行读取和写入操作,那么我假设您正在不同的线程上执行此操作,在这种情况下,请查看 ReaderWriteLock 类,该类将为您进行管理,并允许您提供超时。

http://msdn.microsoft.com/en-us/ library/system.threading.readerwriterlock.aspx

否则,您所需要做的就是以只读模式打开该文件。 那么你应该不会有任何问题:

fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read));

Do you mean you are both reading and writing to the file? Or that an external application is writing to it.

If you are doing the reading and writing then I assume you're doing it on different threads in which case take a look at the ReaderWriteLock class which will do this the management for you, and allow you to provide timeouts.

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx

Otherwise all you need to do is open the file in a read only mode. Then you shouldn't have any problems:

fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read));
千秋岁 2024-07-22 08:23:13

您可以与 IOException 类型进行比较,以检查它是否不是其他类型,

例如

if (ex is FileNotFoundException)

您可能需要查找 System.IO 上的帮助。 该类中的许多异常继承自 IOException。 除了检查是否是另一种类型的异常之外,您可能还需要查看描述消息,或者您可能需要对 shell32.dll 进行 Win32 API 调用。 那里可能有一个函数来检查文件是否被锁定。

另外,如果您绝对需要等待,可以使用循环,但如果您想在等待时执行其他操作,请使用异步线程。

You can compare against the type IOException to check and see if it is not something else

Such as

if (ex is FileNotFoundException)

You might want to look up the help on System.IO. A lot of the exceptions in that class inherit from IOException. Outside of checking to see if it is another type of exception you may have to look in the message of the description or you might look into making a Win32 API call into shell32.dll. There may be a function in there to check if a file is locked.

Also, if you absolutely need to wait you can use loop, but if you want to do other actions while waiting use an asynchronous thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文