【问题标题】:How to check if a file is currently open or being written to in .NET?如何检查文件当前是否打开或正在.NET 中写入?
【发布时间】:2015-08-07 03:47:19
【问题描述】:

我正在尝试确定文件当前是否打开或正在使用 C# 写入。我见过类似的 SO 问题,所有问题都具有与我的代码类似的解决方案,它尝试对文件执行 File.Open。但是当我使用下面的代码运行程序时,我还手动打开了文件,我得到了“文件当前未锁定”的意外结果。有什么想法/建议/我缺少什么吗?

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;
        }
    }
}

【问题讨论】:

  • 至少在那个file.Open()上加上一个using(...)声明。
  • 手动打开文件时确定文件被锁定了吗?
  • @whoisj 你认为stream.Dispose() 有什么stream.Close() 还没有做到?
  • 也许您在将文件读入内存的程序中打开文件。如果您使用FileInfo.Open 在另一个程序中打开它并且不关闭它,也许这会起作用。试一试:)
  • 很难猜测“也手动打开文件”可能意味着什么。好吧,不是你想的那样。许多读取 .txt 文件的程序只是读取其内容并再次关闭文件。像记事本或 VS。

标签: c# .net io


【解决方案1】:

文本文件通常不会被锁定——它们的信息通常会被拉取并加载到内存中,所以除非你试图在另一个程序正在加载文件的同一时刻访问它(这会非常快)然后你应该没有问题。

来源 - Similar question

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

【讨论】:

  • 不幸的是,OP 不能依赖通常的行为。
  • 你确定吗?请为您的答案添加参考。
  • @BehzadKhosravifar 这个答案是完全正确的,包括您自己在内的任何人都可以轻松验证。只需尝试在记事本中打开同一个文件两次。
  • 赞成。这个答案是 100% 正确的。我只是想详细说明我的答案。尼古拉斯是绝对正确的。
  • 总是欢迎详细说明,您也可以 +1 :) 我们知道的越多越好。
【解决方案2】:

许多文本编辑器实际上并未对文件设置文件锁。例如,我使用 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");
    }
}

我希望这有助于澄清发生了什么。

如果这个答案被证明是不正确的并且让我的家人蒙羞,我发誓我会自食其果。

【讨论】:

  • 谢谢。我现在看到,仅使用应用程序打开文件并不一定会锁定它。因此,如果正在写入文件,那么在此期间它是否被视为“打开”和“锁定”?我看到这模拟了打开文件的应用程序,但我想确认正在写入的文件也被认为是锁定的。
  • 是的,如果正在写入文件,那么它会被锁定。但是,对于文本文件,写入会非常快。如果你想模拟打开文件,只需要用word打开,word会保持流打开。
  • 是的,必须打开并锁定文件才能写入或读取。这些操作非常快速,大多数编辑器在操作完成后立即关闭文件并使用 RAM 作为工作区。尼古拉斯是正确的。如果编辑器(在本例中为 Word)在加载文件后没有关闭文件,则文件将保持锁定状态。甚至认为它没有被主动读取或写入。
  • 不,不同的应用程序处理打开文本文件的方式不同。所以正如我所说,打开文本文件的最常见方法是锁定它,阅读所有文件,然后立即解锁。 Word(和其他一些程序)通过锁定它然后在它打开的整个过程中保持锁定来处理它。
  • 要模拟它(如果你想用代码来做),只需创建一个新项目,使用var reader = new StreamReader(fileLocation) 打开文本文件,然后使用while(true) 循环永远循环。该文件在您的阅读器流中打开并且从未关闭,使其锁定。
猜你喜欢
  • 1970-01-01
  • 2016-05-24
  • 1970-01-01
  • 2015-06-17
  • 1970-01-01
  • 2012-07-02
  • 2012-11-14
  • 1970-01-01
相关资源
最近更新 更多