在 Windows/NTFS 中附加到文件是原子的吗?

发布于 2024-09-05 10:36:06 字数 232 浏览 1 评论 0 原文

如果我从多个进程编写一个简单的文本日志文件,它们是否会覆盖/损坏彼此的条目?

(基本上,这个问题 Is fileappendatomic-in-unix">Is fileappendatomicin-UNIX? 但对于 Windows/ NTFS。)

If I'm writing a simple text log file from multiple processes, can they overwrite/corrupt each other's entries?

(Basically, this question Is file append atomic in UNIX? but for Windows/NTFS.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

眼角的笑意。 2024-09-12 10:36:06

您可以在本地文件上获得原子追加。使用 FILE_APPEND_DATA 访问权限打开文件(在 WDK 中记录)。当您省略 FILE_WRITE_DATA 访问时,所有写入将忽略当前文件指针并在文件末尾完成。或者您可以使用 FILE_WRITE_DATA 访问,并在重叠结构中指定它的追加写入(Offset = FILE_WRITE_TO_END_OF_FILE 和 OffsetHigh = -1 记录在 WDK)。

追加行为在通过不同句柄的写入之间正确同步。我经常使用它来记录多个进程。我确实在每次打开时将 BOM 写入偏移量 0,并附加所有其他写入。时间戳不是问题,可以在需要时对它们进行排序。

You can get atomic append on local files. Open the file with FILE_APPEND_DATA access (Documented in WDK). When you omit FILE_WRITE_DATA access then all writes will ignore the the current file pointer and be done at the end-of file. Or you may use FILE_WRITE_DATA access and for append writes specify it in overlapped structure (Offset = FILE_WRITE_TO_END_OF_FILE and OffsetHigh = -1 Documented in WDK).

The append behavior is properly synchronized between writes via different handles. I use that regularly for logging by multiple processes. I do write BOM at every open to offset 0 and all other writes are appended. The timestamps are not a problem, they can be sorted when needed.

平生欢 2024-09-12 10:36:06

即使追加是原子的(我不相信它是原子的),它也可能不会给你你想要的结果。例如,假设日志包含时间戳,则期望将更新的日志附加在较旧的日志之后似乎是合理的。对于并发性,这种保证不成立 - 如果多个进程正在等待写入同一个文件,则其中任何一个进程都可能获得写锁 - 而不仅仅是最旧的进程在等待。因此,日志可能会不按顺序写入。

如果这不是理想的行为,您可以通过将所有进程的日志条目发布到共享队列(例如命名管道)来避免这种情况。然后,您将有一个进程从该队列写入日志文件。这避免了并发问题,确保日志按顺序写入,并且在文件追加不是原子性时有效,因为文件仅由一个进程直接写入。

Even if append is atomic (which I don't believe it is), it may not give you the results you want. For example, assuming a log includes a timestamp, it seems reasonable to expect more recent logs to be appended after older logs. With concurrency, this guarantee doesn't hold - if multiple processes are waiting to write to the same file, any one of them might get the write lock - not just the oldest one waiting. Thus, logs can be written out of sequence.

If this is not desirable behaviour, you can avoid it by publishing logs entries from all processes to a shared queue, such as a named pipe. You then have a single process that writes from this queue to the log file. This avoids the conccurrency issues, ensures that logs are written in order, and works when file appends are not atomic, since the file is only written to directly by one process.

烧了回忆取暖 2024-09-12 10:36:06

从这个 MSDN 页面创建和打开文件:

应用程序还使用 CreateFile 指定是否要共享文件以进行读取、写入、两者或两者都不共享。这称为共享模式。未共享的打开文件(dwShareMode 设置为零)无法由打开该文件的应用程序或其他应用程序再次打开,直到其句柄被关闭。这也称为独占访问。

和:

如果您指定的访问或共享模式与先前调用中指定的模式冲突,则 CreateFile 将失败。

因此,如果您使用 CreateFile 而不是说 File.Open 对文件访问没有相同级别的控制,您应该能够以这样的方式打开文件:它不会被其他进程损坏。

显然,您必须向进程添加代码以应对无法独占访问日志文件的情况。

From this MSDN page on creating and opening Files:

An application also uses CreateFile to specify whether it wants to share the file for reading, writing, both, or neither. This is known as the sharing mode. An open file that is not shared (dwShareMode set to zero) cannot be opened again, either by the application that opened it or by another application, until its handle has been closed. This is also referred to as exclusive access.

and:

If you specify an access or sharing mode that conflicts with the modes specified in the previous call, CreateFile fails.

So if you use CreateFile rather than say File.Open which doesn't have the same level of control over the file access, you should be able to open a file in such a way that it can't get corrupted by other processes.

You'll obviously have to add code to your processes to cope with the case where they can't get exclusive access to the log file.

何时共饮酒 2024-09-12 10:36:06

不,不是。如果您需要此文件,请参阅 事务性 NTFS Windows Vista/7。

No it isn't. If you need this there is Transactional NTFS in Windows Vista/7.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文