如何锁定文件

17

请告诉我如何在C#中锁定文件。

谢谢。


这可能会导致数十个不同的答案,它们都是有效的。请添加更多具体信息。(顺便说一句,仅仅打开文件就可以阻止其他人访问它。) - Wim ten Brink
这对我有用:https://dev59.com/hVPTa4cB1Zd3GeqPi2Z_#4693064 - Vbp
https://github.com/Tyrrrz/LockFile - ElektroStudios
2个回答

46

只需独占地打开它:

using (FileStream fs = 
         File.Open("MyFile.txt", FileMode.Open, FileAccess.Read, FileShare.None))
{
   // use fs
}

Ref

更新:根据发帖者的评论,根据在线MSDN文档,File.Open在.NET Compact Framework 1.0和2.0中得到支持。


1
不确定这是否回答了问题。OP正在寻找FileStream.Lock方法,但在紧凑框架中不存在。Lock防止其他进程修改文件,但仍然允许它们读取文件。我认为您的方法会完全阻止其他进程。 - MusiGenesis
@Mitch:你的回答可能正是他所需要的,但如果他想找到一种WinMo的方法来实现FileStream.Lock的功能(阻止写入访问但不阻止读取访问,并锁定文件中的字节范围),那么这并不适用。 - MusiGenesis
@MitchWheat 如果我像这样打开很多文件流,会导致内存泄漏或降低系统性能吗? - techno

0

如果另一个线程正在尝试访问文件,则 FileShare.None 将抛出“System.IO.IOException”错误。

您可以使用一些带有 try / catch 的函数来等待文件被释放。 示例 here.

或者,您可以在访问写功能之前使用一些“虚拟”变量的锁语句:

    // The Dummy Lock
    public static List<int> DummyLock = new List<int>();

    static void Main(string[] args)
    {
        MultipleFileWriting();
        Console.ReadLine();
    }

    // Create two threads
    private static void MultipleFileWriting()
    {
        BackgroundWorker thread1 = new BackgroundWorker();
        BackgroundWorker thread2 = new BackgroundWorker();
        thread1.DoWork += Thread1_DoWork;
        thread2.DoWork += Thread2_DoWork;
        thread1.RunWorkerAsync();
        thread2.RunWorkerAsync();
    }

    // Thread 1 writes to file (and also to console)
    private static void Thread1_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i < 20; i++)
        {
            lock (DummyLock)
            {
                Console.WriteLine(DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss") + " -  3");
                AddLog(1);
            }
        }
    }

    // Thread 2 writes to file (and also to console)
    private static void Thread2_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i < 20; i++)
        {
            lock (DummyLock)
            {
                Console.WriteLine(DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss") + " -  4");
                AddLog(2);
            }
        }
    }

    private static void AddLog(int num)
    {
        string logFile = Path.Combine(Environment.CurrentDirectory, "Log.txt");
        string timestamp = DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss");

        using (FileStream fs = new FileStream(logFile, FileMode.Append,
            FileAccess.Write, FileShare.None))
        {
            using (StreamWriter sr = new StreamWriter(fs))
            {
                sr.WriteLine(timestamp + ": " + num);
            }
        }

    } 

你也可以在实际的写入函数中(即在AddLog内部)使用“lock”语句,而不是在后台工作线程的函数中使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接