如何检查文件当前是否打开或正在写入 .NET?

How to check if a file is currently open or being written to in .NET?

我正在尝试确定文件当前是否打开或正在使用 C# 写入。我见过类似的 SO 问题,所有问题的解决方案都与我的代码类似,它尝试对文件执行 File.Open。但是当我 运行 使用下面代码的程序,并且我还手动打开文件时,我得到了 "File is currently NOT locked" 的意外结果。 thoughts/suggestions/anything 我遗漏了什么?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;

namespace TestIfFileAccessed
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = @"C:\TEMP\testFile.txt";
            FileInfo filepath = new FileInfo(path);

            if (IsFileLocked(filepath)) {
                Console.WriteLine("File is currently locked");
                Console.ReadLine();
            }
            else
            {
                Console.WriteLine("File is currently NOT locked");
                Console.ReadLine();
            }
        }

        public static bool IsFileLocked(FileInfo file)
        {
            FileStream stream = null;

            try
            {
                stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
            }
            catch (IOException)
            {
                //the file is unavailable because it is:
                //still being written to
                //or being processed by another thread
                //or does not exist (has already been processed)
                return true;
            }
            finally
            {
                if (stream != null)
                    stream.Close();
            }

            //file is not locked
            return false;
        }
    }
}

文本文件通常不会被锁定 - 它们的信息通常被提取并加载到内存中,因此除非您试图在另一个程序加载文件的同一时刻访问它(这会非常快)那么你应该没有任何问题。

来源 - Similar question

编辑:如果它在 word 中打开,那么您将遇到问题,因为 Word 保持流打开。尝试在 Word 中打开文件(如果有的话)并再次 运行 您的代码,我相信它应该可以工作。否则,如果您想查看它是否在记事本中打开,则必须扫描系统上的当前进程 运行 以查找记事本并检查该进程是否打开了该文件。

许多文本编辑器实际上并没有在文件上放置文件锁。例如,我使用 Sublime Text 3 来编辑文件。我可以在 Sublime 中打开一个 .txt 文件,然后在另一个编辑器(例如记事本)中打开 SAME 文件。 .txt 文件上没有文件锁。

发生的事情是,当您打开文件时,编辑器将文件加载到内存中,然后立即关闭。它们没有打开。编辑器只会让文件打开足够长的时间来加载它们,但是,从技术上讲,当编辑器将文件加载到 RAM 中时,文件会被锁定。它不会持续很长时间,因为这个操作非常快。

如果您在调用 IsFileLocked(filepath) 之前执行 filepath.Open();,您可能会导致文件锁定并按预期看到文件锁定错误。如果您想对此进行测试,我建议您在 Main 方法中尝试使用此代码:

static void Main(string[] args)
{
    string path = @"C:\TEMP\testFile.txt";

    FileInfo filepath = new FileInfo(path);
    Console.WriteLine("Opening \"filepath\"");
    filepath.Open();

    FileInfo filepath2 = new FileInfo(path);

    if (IsFileLocked(filepath2)) {
        Console.WriteLine("File is currently locked");
    }
    else
    {
        Console.WriteLine("File is currently NOT locked");
    }

    Console.WriteLine("Closing \"filepath\"");
    filepath.Close();

    if (IsFileLocked(filepath2)) {
        Console.WriteLine("File is currently locked");
    }
    else
    {
        Console.WriteLine("File is currently NOT locked");
    }
}

我希望这有助于澄清正在发生的事情。

如果这个答案被证明是错误的并且给我的家人丢脸,我誓死不渝。