C#判断本地文件是否处于打开状态的方法

追风的人
追风的人
发布时间:2026-10-13| 4人浏览过
原创

本文讲述如何在C#中判断本地文件是否被其他程序打开(即存在独占连接)。利用 Windows `kernel32.dll` API 进行轻量级检测,避免多线程或进程间文件读写时的“文件正在使用中”异常。

原理与目标

操作系统在同一时刻通常只允许一个流对特定文件建立独占连接。在频繁进行文件读写的程序中,直接操作未检查的文件极易导致异常。_lopen 函数可用于尝试以指定共享权限打开文件,若返回错误指针则表示文件已被锁定。

准备条件

  • C# 运行环境(.NET Framework 或 .NET Core/5+)
  • 需要引用 System.Runtime.InteropServices 命名空间
  • 拥有目标文件的访问权限

实现步骤

第1步:创建检测工具类

目的:封装底层调用逻辑,对外提供简单的整数状态返回值。

说明:该类包含以下关键定义:

  • DllImport("kernel32.dll"):引入外部动态链接库。
  • _lopen:尝试打开文件的核心函数。
  • CloseHandle:释放资源。
  • HFILE_ERROR:表示操作的错误状态标识。
using System;
using System.IO;
using System.Runtime.InteropServices;

public class FileStatus
{
    // 声明 Windows API 函数
    [DllImport("kernel32.dll")]
    private static extern IntPtr _lopen(string lpPathName, int iReadWrite);
    
    [DllImport("kernel32.dll")]
    private static extern bool CloseHandle(IntPtr hObject);

    // 常量定义
    private const int OF_READWRITE = 2;        // 读写模式
    private const int OF_SHARE_DENY_NONE = 0x40; // 不拒绝任何共享访问
    private static readonly IntPtr HFILE_ERROR = new IntPtr(-1); // 错误指针

    /// <summary>
    /// 判断文件是否被占用
    /// </summary>
    /// <param name="fileFullName">文件绝对路径</param>
    /// <returns>0: 未被占用, 1: 已被占用, -1: 文件不存在</returns>
    public static int FileIsOpen(string fileFullName)
    {
        if (!File.Exists(fileFullName))
        {
            return -1;
        }
        
        // 尝试以无限制共享方式打开文件
        IntPtr handle = _lopen(fileFullName, OF_READWRITE | OF_SHARE_DENY_NONE);
        
        // 如果返回错误句柄,说明文件正被独占占用
        if (handle == HFILE_ERROR)
        {
            return 1;
        }
        
        // 释放句柄
        CloseHandle(handle);
        return 0;
    }
}

第2步:编写调用测试逻辑

目的:模拟真实场景,开启一个文件流并观察检测结果的变化。

入口:控制台应用程序 Main 方法。

动作:

  1. 构建测试文件路径(基于当前应用目录)。
  2. 使用 FileStream 和 BinaryReader 保持文件打开状态。
  3. 调用 FileStatus.FileIsOpen 查看状态。
  4. 关闭阅读器再次检测。
class Program
{
    static void Main(string[] args)
    {
        // 获取应用程序基础路径
        string testFilePath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase + @"testOpen.txt";

        try
        {
            // 模拟文件被打开的场景
            FileStream fs = new FileStream(testFilePath, FileMode.OpenOrCreate, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs);
            br.Read();

            Console.WriteLine("文件被打开");
            int result = FileStatus.FileIsOpen(testFilePath);
            Console.WriteLine(result); // 预期输出: 1

            // 清理资源
            br.Close();
            fs.Close();

            Console.WriteLine("文件被关闭");
            result = FileStatus.FileIsOpen(testFilePath);
            Console.WriteLine(result); // 预期输出: 0
        }
        catch (Exception ex)
        {
            Console.WriteLine($"发生错误: {ex.Message}");
        }

        Console.ReadLine();
    }
}

完成判断

当 FileIsOpen 返回 0 时,表示文件目前空闲,可安全执行后续读写操作;返回 1 时表示文件已被其他进程占用,建议采取等待重试或提示用户的策略。若在部署环境中发现行为不一致,请检查杀毒软件是否对该文件进行了特殊锁定监控。

以上就是C#判断本地文件是否处于打开状态的详细内容,更多关于C#文件操作技巧的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。