等待文件可写

2024-02-27

我正在开发一个将数据写入文件的工具。

在某些时候,文件可能会被“锁定”,并且在其他句柄关闭之前不可写入。

我可以使用CreateFileAPI 处于循环状态,直到文件可用于写入访问。

但我有两个问题使用CreateFile循环中:

  • 硬盘驱动器(缓存)始终在运行...?!
  • 我需要打电话CreateFile再次获得具有不同标志的有效写入句柄...?!

所以我的问题是:

等待文件可写并立即获得有效句柄的最佳解决方案是什么?

是否有任何事件解决方案或任何东西,允许一次“排队/保留”句柄,以便与其他人不存在“不受控制”的竞争条件?


文件可以“锁定”有两个原因:

  1. 实际的文件锁这会阻止写入,并可能阻止读取文件。
  2. 在没有共享访问权限的情况下打开文件(意外或自愿)这甚至会阻止您打开手柄。如果你已经看到了CreateFile失败,这很可能是这种情况,而不是真正的锁。

There are conceptually[1] at least two ways of knowing that no other process has locked a file without busy waiting:

  1. 通过找出谁持有锁并等待进程或线程退出(或者,通过彻底杀死它们......)
  2. 通过自己锁定文件

谁持有锁?
找出锁的所有者是相当令人讨厌的,你可以通过完全无证 SystemLocksInformation与未记录的类一起使用NtQuerySystemInformation函数(后者“只是未记录”,但前者没有太多记录,以至于很难找到任何信息)。返回的结构体解释here http://j00ru.vexillium.org/?p=269,并且它包含一个所属线程 ID。

Luckily,持有一把锁就意味着持有一个把手。关闭文件句柄将解锁所有文件范围。这意味着:没有把手就没有锁。

换句话说,问题也可以表示为“谁持有文件的打开句柄?”。当然,并非所有持有文件句柄的进程都会锁定该文件,但是没有进程有句柄保证没有进程锁定该文件。
找出哪些进程打开了文件的代码要容易得多(使用重新启动管理器)并且是一应俱全 http://blogs.msdn.com/b/oldnewthing/archive/2012/02/17/10268840.aspx在雷蒙德·陈的网站上。

现在您知道哪些进程和线程正在持有文件句柄和锁,请列出所有线程/进程句柄并使用WaitForMultipleObjects在进程句柄列表上。当进程退出时,所有句柄都将关闭。
这也透明地处理了“锁定”的可能性,因为进程不共享访问。

自己锁定文件
您可以使用LockFileEx,它异步运行。注意LockFileEx需要一个已打开的有效句柄either读或写权限(获得写权限可能是不可能的,但读应该几乎总是有效——即使你实际上被阻止了reading通过独占锁,仍然可以创建一个句柄可以阅读如果没有锁)。

然后,您可以通过以下事件等待异步锁定完成:OVERLAPPED结构,或在完成端口上,甚至还可以同时做其他有用的事情。一旦您锁定了文件,您就知道没有其他人锁定了它。


[1] The wording "conceptually" suggests that I am pretty sure either method will work, but I have not tested them.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

等待文件可写 的相关文章

  • 如何使用WinAPI识别光驱中的光盘类型?

    我正在编写一个适用于音频 CD 和混合 CD 的应用程序 我想要一种方法来确定应用程序使用的驱动器中当前是否存在音频或混合类型 至少有一个音轨 光盘 到目前为止 我能够通过以下方式识别该驱动器是CD ROMGetDriveType 然而 事
  • 从 Visual Studio 运行时,STARTUPINFO.wShowWindow 为 0

    我在调试名为 Notepad2 的开源记事本替代品中的功能时偶然发现了一个问题 更具体地说 是一个名为 Notepad2 的更新版本 Notepad2 mod https github com XhmikosR notepad2 mod 它
  • 从 32 位拖放到 64 位

    我正在编写一个接受文件拖放的 C 程序 当它以 32 位编译时 它在任何情况下都可以工作 但当它以 64 位编译时 它仅适用于从 64 位应用程序拖动的文件 32 位 gt 32 位 成功 64 位 gt 64 位 成功 64 位 gt 3
  • SetForegroundWindow 不适用于最小化进程[重复]

    这个问题在这里已经有答案了 找不到关于这个主题的任何好的答案 所以也许有人可以帮助我 我正在制作一个小型个人程序 我想将某个应用程序带到前台 它已经可以工作了 但是有一个小问题 当进程最小化时 我的代码将无法工作 该进程不会像未最小化时那样
  • 消息循环如何使用线程?

    我有点困惑 想知道我是否被误导了 在另一篇文章中 我被告知 只有当你显式创建新线程时才会创建它们 C 程序默认是单线程的 当我打开未在 ollydbg 中显式创建新线程的程序时 我多次注意到通常有 2 个线程在运行 我想了解消息循环如何在不
  • Win32 DrawText 行高

    我正在调用 Win32DrawText函数将一些文本输出到设备上下文中 文本很长 可以很好地换行到第二行 问题是我需要稍微减少行之间的间距 我想减少行高 关于如何做到这一点有什么想法吗 我只想打电话DrawText两次 每行一次 但随后我必
  • 使用 WinAPI 在 C# 中隐藏任务栏窗口

    相信我 我用谷歌搜索过它 并期望它是一个相当容易找到的东西 事实证明并非如此 我有窗把手 但没有表格 我该怎么做 谢谢 声明这些 DllImport user32 dll SetLastError true static extern in
  • 用C#排列桌面图标

    好吧 伙计们 这就是我想要实现的目标 我希望所有无序的桌面图标在单击按钮时都排列在桌面的左上角 这是我正在使用的代码 DllImport user32 dll private static extern IntPtr GetDesktopW
  • 在 Windows 上实现堆栈跟踪 [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在为我正在编写的游戏实现一个崩溃报告工具 并且我想为该报告提供 相当 详细的本机堆栈跟踪 我已经在 GNU Linux 上实现
  • 如何防止用户杀死C#应用程序[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 如果您使用 ESET Smart S
  • 我需要为我的应用程序制作和加载多大尺寸的 ImageList 图标(考虑更高的 DPI)?

    我有一个CListCtrl http msdn microsoft com en us library hfshke78 aspx控制 或ListView http msdn microsoft com en us library wind
  • 如何检测媒体是否已插入可移动驱动器/读卡器

    我有一个读卡器 未插入记忆棒 当我插入计算机时 它在 我的电脑 中显示一个空驱动器 是否有可能知道驱动器是否有媒体 抱歉我不知道如何称呼它 或没有 我找到的建议MSalters to use IOCTL STORAGE CHECK VERI
  • 在 C++\Win32 中编辑控件文本更改消息

    与 NET for C Win32 中的 TextChanged 属性匹配的消息是什么 假设你正在谈论编辑控件 http msdn microsoft com en us library bb775458 VS 85 aspx EN CHA
  • Windows Server / Datacenter:设置 CPU 关联性 > 64 个核心

    SetThreadAffinityMask 允许为 64 个逻辑核心 处理器 设置关联掩码 但是 Windows Datacenter 最多可以有 64 个 CPU 每个 CPU 都有多个内核 请参阅here http social tec
  • 如何检测Windows 8.1开始菜单?

    当我们在 Windows 8 1 上按下开始菜单时 它会以磁贴的形式显示所有新的开始菜单以及应用程序 该菜单显示在整个屏幕上 有没有办法检测这个菜单是否在 C 中打开 8 1 SDK 中是否有 winAPI 可以执行此操作 提前致谢 调用
  • Windows 上的本机窄字符串编码是什么?

    Subversion API 有一个功能数量 http subversion apache org docs api latest svn utf 8h html用于从 本机编码 字符串转换为以 UTF 8 编码的字符串 我的问题是 Win
  • 如何获取当前所选键盘布局的显示名称

    我需要以语言栏显示输入语言的方式向用户显示输入语言列表 例如 目前我有 class Program static void Main string args var langs InputLanguage InstalledInputLan
  • Windows 8 SDK 中的 DirectX

    Summary 是否应该从针对 Windows 8 的应用程序中删除 directX 包含文件 Details 我是 Windows 开发新手 我正在尝试使用 Visual Studio 2012 如果可能 在 Windows 8 上编译
  • 使用 StretchDIBits 使用 Delphi 6 处理条形码图像 - 输出中缺少条形线

    我的应用程序是在 Delphi 6 中开发的 由于后台处理和大量数据 它消耗大约 60MB 120MB 物理内存 这是一个资源密集型应用程序 该应用程序的功能之一是在进行某些处理后创建条形码图像 如果用户继续生成条形码 那么至少十分之一的条
  • 为什么 FindWindow 找到了 EnumChildWindows 找不到的窗口?

    我正在寻找一个类名称为 CLIPBRDWNDCLASS 的窗口 它可以在办公应用程序和其他应用程序中找到 如果我使用 FindWindow 或 FindWindowEx 我找到第一个具有此类的 HWND 但我想要all具有该类的窗口 因此我

随机推荐

  • 如何直观地显示 java ResultSet?

    我正在寻找一种在屏幕上显示 java sql ResultSet 的方法 最好内置于java或swing中 如果这两个都没有一个简单的好方法 我会考虑 spring How 循环 ResultSet 的结果并将其放入 TableModel
  • 如何在 Google 电子表格中添加标题

    我在用gdata spreadsheet 3 0jar 用于在 Google 电子表格中输入数据 我在用 new ListEntry getCustomElements setValueLocal Header Name Value 但我不
  • 有没有一种简单的方法来扩展现有的激活函数?我的自定义 softmax 函数返回: 操作具有“无”梯度

    我想通过仅使用向量中的前 k 个值来实现使 softmax 更快的尝试 为此 我尝试为张量流实现一个自定义函数以在模型中使用 def softmax top k logits k 10 values indices tf nn top k
  • Angular 2 组件@Input 不起作用

    我一直试图将属性值传递到我的组件中 从我读到的一切看起来都是正确的 但它仍然不起作用 我的测试值以空值输出到屏幕和控制台 这是我的测试组件 import Component Input from angular2 angular2 Comp
  • 如何检查字符串是否是全语法?

    我想创建一个函数 它接受一个字符串作为输入 并检查该字符串是否是全语法 全语法是包含字母表中每个字母的一段文本 我编写了以下代码 该代码有效 但我正在寻找一种替代方法 希望是一种简短的方法 import string def is pang
  • 从 Python 中的 code.interact() 恢复代码执行

    在使用调试时打开交互式控制台后 code interact local locals 我怎样才能恢复代码执行 我已经检查了 代码 模块和搜索堆栈溢出的文档 但找不到任何内容 这与退出任何 Python 解释器会话的方式相同 发送文件结束字符
  • 电话号码格式应该是国际格式,iPhone中是否有用于电话号码验证的正则表达式

    电话号码应该是国际电话号码 用户必须输入带有国家 地区代码的完整电话号码 为此 我需要一个正则表达式来格式化电话号码 对于真正的正则表达式测试使用正则表达式套件精简版 http regexkit sourceforge net RegexK
  • 是否可以在 _LoginPartial.cshtml 中使用 @model ?

    我需要从我的数据库获取一些数据 LoginPartial cshtml 是否可以使用 model in LoginPartial cshtml 或者说它是如何完成的 就在 using WebApp Services然后直接从服务中检索数据
  • OpenCL 编译器预处理定义?

    我正在 Snow Leopard 上开发 OpenCL 代码 并且了解 OpenCL 即时编译是由 Clang LLVM 完成的 是否使用了 C 预处理器 有没有办法使用编译器设置预处理定义 存在哪些定义 我希望代码知道它是为 CPU 还是
  • Java 8 列表到嵌套映射

    我有一个班级名单A like class A private Integer keyA private Integer keyB private String text 我要转让aList嵌套Map映射于keyA and keyB 所以我创
  • 正则表达式的金钱

    I have asp TextBox保持货币价值 即 1000 1000 0 和 1000 00 由于俄罗斯标准 逗号是分隔符 What ValidationExpression我要使用适当的asp RegularExpressionVal
  • 如何指定 RTL 特定的可绘制对象

    我有几张从右到左看起来不同的图像 是否可以创建 rtl 特定的可绘制目录或文件名的一些 rtl 后缀以自动加载相关图像 看起来像 ldrtl 后修复 从 17 级添加 仅适用于布局目录 现在回答这个问题已经很晚了 但我想分享一个我刚刚发现的
  • 有人用 VS2010 RTM 编译 OverviewMargin 吗?

    由于我严重上瘾岩石卷轴 http www hanselman com blog IntroducingRockScroll aspx 我正在寻找一个替代品 https stackoverflow com questions 2672277
  • 让Java文件传输更高效

    我有两台无线计算机连接到 N 个无线路由器 每台 PC 的连接速度都在 108 150Mbps 之间 理论上 在绝对最佳的条件下 我应该能够以 13 5MB s 到 18 75MB s 的速度传输 第一台计算机 正在发送 使用非常快的 SS
  • Android 模拟器上的低功耗蓝牙

    我研究了关于蓝牙低功耗 http developer android com guide topics connectivity bluetooth le html 但我没有支持 BLE 设备进行测试 因此 我想问 Android模拟器支持
  • 如何使用 JavaScript 将图像转换为 Base64 字符串?

    我需要将图像转换为 Base64 字符串 以便可以将图像发送到服务器 有没有相关的 JavaScript 文件 否则 我该如何转换它 您可以选择多种方法 1 方法 FileReader 通过以下方式将图像加载为 blobXMLHttp请求
  • 为什么弹性项目受限于父级尺寸?

    考虑以下示例 body margin 0 box sizing border box parent min height 100vh width 50vw margin 0 auto border 1px solid red display
  • 过滤传出 SignalR Core Hub 消息

    我正在使用 SignalR 和 Net 5 0 并利用集线器过滤器 https learn microsoft com en us aspnet core signalr hub filters view aspnetcore 5 0对我的
  • 如何使批处理文件删除它自己的目录?

    好吧 我很抱歉我对此很陌生 但我试图让我的批处理文件在启动后删除它自己的目录 这是我的文件夹的排列方式 Folder1 删除 bat 我的目标是让 delete bat 在启动 delete bat 后删除 Folder1 这是我的代码 r
  • 等待文件可写

    我正在开发一个将数据写入文件的工具 在某些时候 文件可能会被 锁定 并且在其他句柄关闭之前不可写入 我可以使用CreateFileAPI 处于循环状态 直到文件可用于写入访问 但我有两个问题使用CreateFile循环中 硬盘驱动器 缓存