Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何测试当前是否正在写入文件_C#_.net - Fatal编程技术网

C# 如何测试当前是否正在写入文件

C# 如何测试当前是否正在写入文件,c#,.net,C#,.net,我有一个应用程序,必须检查一个文件夹,并读取任何文件复制到它。 如何测试该文件夹中的文件当前是否正在写入?我只想读文件 已将所有数据写入并已关闭。它不干净,但可以工作: try { using (Stream stream = new FileStream("File.txt")) { } } catch { // Check if file is in use (or whatever else went wrong), and do any user co

我有一个应用程序,必须检查一个文件夹,并读取任何文件复制到它。 如何测试该文件夹中的文件当前是否正在写入?我只想读文件
已将所有数据写入并已关闭。

它不干净,但可以工作:

try
{
    using (Stream stream = new FileStream("File.txt"))
    {
    }
} 
catch 
{
    // Check if file is in use (or whatever else went wrong), and do any user communication that you need to
}

我并不特别喜欢使用异常作为条件,但据我所知,这是最简单、最好(也是唯一可靠)的方法

我能想到的唯一一件事是,当文件被写入时,会在文件上放置一个文件锁,因此会阻止您对其进行写入(抛出文件被另一个进程锁定的System.IO异常),但这并不是万无一失的。例如,通过打开和关闭每个块的文件,可以将文件分块写入

因此,您可以使用try/catch块执行此操作:

try
{
   //opening the file
} 
catch(IOException ex)
{
   // file is open by another process
}

选择的数量。我马上想到的一件事是尝试打开文件进行写入。如果引发异常,则仍在将其写入。请等待定义的时间段,然后重试


或者,检查时间戳并仅在时间戳上次更改后1或2分钟内读取文件

当您使用
System.IO.file.OpenWrite(filename)
打开文件时,它应该抛出
IOException


因此,在try-catch中,catch块中执行的代码应该告诉您该文件已打开。

写入的文件通常具有写锁,因此如果您尝试打开该文件进行写入,您将失败;但是,您可能有一个打开、写入和关闭文件的过程,然后重复。 我认为最简单、最安全的方法就是检查最近写入的文件,但不是最近写入的(例如,不是在最后2秒左右)


(L.E.)另一点需要考虑的是,如果您有一个进程在CUNCK(打开写关闭)中写入数据,并且获得文件的专用锁(以检查文件不再被使用),那么您的外部进程将失败。我认为最好是检查时间戳,并且只有在您合理地确定另一个进程完成了写入之后才能获得独占锁。

也许像这样以独占方式打开文件-

System.IO.File.Open(PathToFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None);

可以通过try/catch将其放置在循环中,直到其成功。

捕获异常非常昂贵。您应该尝试使用以下方法:

msdn页面上有一个非常清晰的示例。这将为您提供有关更改、创建、删除和重命名的精彩事件

将文件复制到文件夹中,并在完成捕获重命名事件并确保未读取尚未完成的文件时重命名

或者,您可以捕获更改事件,直到(这很棘手)它们不再被触发

使用确定已更改的文件


在AN中打开这些副本,如果失败,就可以捕获异常(因为其他人打开了它)。

< P>如果您对写入过程有任何控制,那么考虑扩充它,以便下面的过程发生:

  • 进程开始写入文件“filename.xyz”
  • 进程写入更多文件“filename.xyz”
  • 进程完成写入文件“filename.xyz”
  • 进程将另一个(零长度,空)文件写入名为“filename.xyz.done”的文件夹

  • 您可以将“.done”文件作为开始处理文件的触发器。同样,只有当您能够修改写入文件的过程时,这才有效。

    我认为try-catch基本上是测试文件的唯一故障安全方法。可惜他们在文件或FileInfo类中没有IsOpen属性..+1:这是唯一的方法。如果有对文件对象“IsOpen”的调用,则在调用IsOpen和打开文件之间没有任何东西可以阻止另一个进程锁定文件。看你是否能得到一个锁的唯一方法就是试着锁上它(然后保持它锁上)。他试图解决的问题本质上容易受到竞争条件的影响。正如我在下面的回答中所解释的,如果“写入过程”一次写入一个块(在连续写入之间关闭文件),那么上述方法实际上将失败。我认为有这样一个进程比有一个进程在X秒内什么都不写,然后在你开始工作的时候突然重新开始写的可能性要大得多。无论如何,不管采用哪种方法,都需要额外的同步,这是肯定的。@Binary-添加了“且仅可靠”,谢谢@Virgil-没错,但事实是,如果不亲自尝试锁定文件,就无法锁定文件(或查看其是否已锁定)以供使用。@Virgil-然后,当您的方法找不到句柄并即将返回时,该文件会被另一个进程锁定。那又怎样?外部程序也应该处理这种情况。举一个例子,如您所说,写入进程之间共享的日志或公共日志。只要某个进程需要日志,就会打开它,该进程负责安全地获得文件锁。如果它没有获得文件锁,那么它应该正确地处理该异常,比如睡一会儿或者稍后再试。如果您只是查看时间戳,那么没有可靠的方法可以通过时间戳知道当您尝试获取文件锁时日志将写入哪个位置。这里的关键字是“应该”。我们现在都知道,并非所有的应用程序都。。。。完美的这样做的目的是,您对写入这些文件的外部进程知之甚少,而且该进程可能完全超出了您的控制范围。您可能希望在catch中进行有条件的重试。我通常有一个计数器和一个线程。Sleep(500)这样我就不会敲打I/O,并且在发生诸如磁盘崩溃之类的事情时仍然可以退出。@willsan-如果答案对您有帮助,请记住接受它。不幸的是,在我的情况下,写入的文件来自第三方程序。@ErnestSoeralaya