You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何设置FileShare.Read后第二个进程仍无法读取.lock文件?

问题原因分析
  1. 第二个进程文件打开的共享模式不兼容
    第一个进程打开.lock文件时指定了FileShare.Read,允许其他进程以只读方式访问该文件。但第二个进程调用File.Open时未显式设置FileShare参数,默认值为FileShare.None(要求独占文件),这与第一个进程的共享权限规则冲突,直接触发IOException。

  2. Unlock操作无意义导致报错
    File.Open创建的文件流默认不会对文件加锁,只有主动调用Lock方法锁定文件后,才能执行解锁操作。直接调用Unlock会因文件从未被锁定而抛出“已解锁”的异常。

解决方法

1. 修正第二个进程的文件打开参数

在第二个进程打开.lock文件时,显式指定FileShare.Read,确保共享模式与第一个进程的规则兼容:

// 替换catch块中的打开代码
using (var infofile = File.Open(lockFileName, FileMode.Open, FileAccess.Read, FileShare.Read))

2. 优化第一个进程的逻辑(可选但关键)

  • 移除多余的File.Delete操作:FileMode.CreateNew会在文件已存在时自动抛出异常,无需提前删除,避免干扰正在运行的第一个进程。
  • 确保写入的用户信息立即落盘:在StreamWriter的using块内添加Flush(),防止第二个进程读取到不完整的内容:
using (var writer = new StreamWriter(lockfile, Encoding.UTF8, 256, true))
{
    string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
    writer.WriteLine(userName);
    writer.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
    writer.Flush(); // 强制将缓存数据写入磁盘
}

3. 删除无效的Unlock调用

直接移除lockfile.Unlock(0,lockfile.Length);这行代码,因为文件流默认未加锁,该操作没有实际意义。

完整修正代码
using System;
using System.IO;
using System.Text;
using System.Security.Principal;

namespace SingleUser
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string lockFileName = ".lock";
            
            try
            {
                // 第一个进程创建文件,允许其他进程只读访问
                using (var lockfile = File.Open(lockFileName, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Read))
                {
                    using (var writer = new StreamWriter(lockfile, Encoding.UTF8, 256, true))
                    {
                        string userName = WindowsIdentity.GetCurrent().Name;
                        writer.WriteLine(userName);
                        writer.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
                        writer.Flush(); // 确保数据写入磁盘
                    }

                    Console.WriteLine("You can access the data. Press Enter to stop working with the file.");
                    Console.ReadLine();
                }
            }
            catch (IOException)
            {
                // 第二个进程读取锁定信息
                try
                {
                    using (var infofile = File.Open(lockFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
                    {
                        using (var reader = new StreamReader(infofile, Encoding.UTF8, false, 256, true))
                        {
                            string user = reader.ReadLine();
                            string time = reader.ReadLine();
                            if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(time))
                            {
                                Console.WriteLine($"{user} works on the file since {time}.");
                            }
                            else
                            {
                                Console.WriteLine("The file is locked by another user, but lock info is incomplete.");
                            }
                        }
                    }
                }
                catch (IOException innerEx)
                {
                    Console.WriteLine($"Failed to read lock info: {innerEx.Message}");
                }
                Console.WriteLine("You can't modify the data. Press Enter to stop.");
                Console.ReadLine();
            }
        }
    }
}

额外说明

  • 若要处理进程异常退出后.lock文件残留的情况,可在第一个进程启动时尝试以独占方式打开.lock文件,判断是否有其他进程占用,再决定是否删除残留文件。
  • 网络文件场景下,需确保操作系统层面的文件共享权限配置正确,避免额外的访问限制。

内容的提问来源于stack exchange,提问作者Thomas W.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 09:49:51