- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
跟进:How to safely update a file that has many readers and one writer?
在我之前的问题中,我发现您可以使用 FileChannel 的锁来确保读写顺序。
但是,如果编写器在写入过程中失败(比如 JVM 崩溃),您将如何处理这种情况?这个基本算法看起来像,
WRITER:
lock file
write file
release file
READER:
lock file
read file
release file
如果 JVM 在 write file
期间崩溃,肯定会释放锁,但现在我有一个不完整的文件。我想要完整的东西总是可读的。要么是旧内容,要么是新内容,不能介于两者之间。
我的第一个策略是写入一个临时文件,然后将内容复制到“实时”文件中(同时确保良好的锁定)。算法是,
WRITER:
lock temp file
write temp file
lock file
copy temp to file
release file
release temp
delete temp
READER:
lock file
read file
release file
一个好处是 delete temp
不会删除临时文件,如果它已经被另一个作者锁定的话。
但是如果 JVM 在copy temp to file
期间崩溃,该算法将无法处理。所以我添加了一个copying
标志,
WRITER:
lock temp file
write temp file
lock file
create copying flag
copy temp to file
delete copying flag
release file
release temp
delete temp
READER:
lock file
if copying flag exists
copy temp to file
delete copying flag
delete temp
end
read file
release file
不会有两件事访问复制
文件,因为它受到文件锁的保护。
现在,这是这样做的方法吗?确保非常简单的事情似乎很复杂。是否有一些 Java 库可以帮我处理这个问题?
编辑
好吧,我设法在第三次尝试中犯了一个错误。读取器在 copy temp to file
时不会锁定 temp。简单地锁定临时文件也不是一个简单的修复!这将导致作者和读者以不同的顺序获取锁,并可能导致死锁。这一直在变得越来越复杂。这是我的第四次尝试,
WRITER:
lock file
write temp file
create copying flag
copy temp to file
delete copying flag
delete temp
release file
READER:
lock file
if copying flag exists
copy temp to file
delete copying flag
delete temp
end
read file
release file
这次临时文件由主锁保护,所以它甚至不需要自己的锁。
编辑 2
当我说 JVM 崩溃时,我实际上是说电源断电了,而您没有 UPS。
编辑 3
我还是犯了另一个错误。您不应该锁定正在写入或读取的文件。这会导致问题,因为除非在 Java 中使用 RandomAccessFile,否则无法同时获得读写锁,而 Java 不实现输入/输出流。
您要做的只是锁定一个保护您正在读取或写入的文件的锁定文件。这是更新后的算法:
WRITER:
lock
write temp file
create copying flag
copy temp to file
delete copying flag
delete temp
release
READER:
lock
if copying flag exists
copy temp to file
delete copying flag
delete temp
end
read file
release
锁定和释放保护文件、临时文件和复制标志。唯一的问题是现在读者锁不能共享,但它永远不可能是真的。读者总是有机会修改文件,因此一开始就设置共享锁是错误的。
最佳答案
尽管没有万无一失、跨操作系统、跨文件系统的解决方案,“写入唯一的临时文件并重命名”策略仍然是您的最佳选择。大多数平台/文件系统都试图使文件重命名(有效地)原子化。请注意,您要使用一个+单独的+锁定文件进行锁定。
因此,假设您要更新“myfile.txt”:
File.createTempFile()
)FileChannel.force(true)
)。在某些平台(windows)上,由于文件操作的限制,你需要做更多的舞蹈(你可以在重命名之前将“myfile.txt”移动到“myfile.txt.old”,并使用“.old”阅读时需要恢复的文件)。
关于java - 如何确保文件写入失败时的文件完整性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/462696/
今天我在一个 Java 应用程序中看到了几种不同的加载文件的方法。 文件:/ 文件:// 文件:/// 这三个 URL 开头有什么区别?使用它们的首选方式是什么? 非常感谢 斯特凡 最佳答案 file
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我有一个 javascript 文件,并且在该方法中有一个“测试”方法,我喜欢调用 C# 函数。 c# 函数与 javascript 文件不在同一文件中。 它位于 .cs 文件中。那么我该如何管理 j
需要检查我使用的文件/目录的权限 //filePath = path of file/directory access denied by user ( in windows ) File fil
我在一个目录中有很多 java 文件,我想在我的 Intellij 项目中使用它。但是我不想每次开始一个新项目时都将 java 文件复制到我的项目中。 我知道我可以在 Visual Studio 和
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a software
我有 3 个组件的 Twig 文件: 文件 1: {# content-here #} 文件 2: {{ title-here }} {# content-here #}
我得到了 mod_ldap.c 和 mod_authnz_ldap.c 文件。我需要使用 Linux 命令的 mod_ldap.so 和 mod_authnz_ldap.so 文件。 最佳答案 从 c
我想使用PIE在我的项目中使用 IE7。 但是我不明白的是,我只能在网络服务器上使用 .htc 文件吗? 我可以在没有网络服务器的情况下通过浏览器加载的本地页面中使用它吗? 我在 PIE 的文档中看到
我在 CI 管道中考虑这一点,我应该首先构建和测试我的应用程序,结果应该是一个 docker 镜像。 我想知道使用构建环境在构建服务器上构建然后运行测试是否更常见。也许为此使用构建脚本。最后只需将 j
using namespace std; struct WebSites { string siteName; int rank; string getSiteName() {
我是 Linux 新手,目前正在尝试使用 ginkgo USB-CAN 接口(interface) 的 API 编程功能。为了使用 C++ 对 API 进行编程,他们提供了库文件,其中包含三个带有 .
我刚学C语言,在实现一个程序时遇到了问题将 test.txt 文件作为程序的输入。 test.txt 文件的内容是: 1 30 30 40 50 60 2 40 30 50 60 60 3 30 20
如何连接两个tcpdump文件,使一个流量在文件中出现一个接一个?具体来说,我想“乘以”一个 tcpdump 文件,这样所有的 session 将一个接一个地按顺序重复几次。 最佳答案 mergeca
我有一个名为 input.MP4 的文件,它已损坏。它来自闭路电视摄像机。我什么都试过了,ffmpeg , VLC 转换,没有运气。但是,我使用了 mediainfo和 exiftool并提取以下信息
我想做什么? 我想提取 ISO 文件并编辑其中的文件,然后将其重新打包回 ISO 文件。 (正如你已经读过的) 我为什么要这样做? 我想开始修改 PSP ISO,为此我必须使用游戏资源、 Assets
给定一个 gzip 文件 Z,如果我将其解压缩为 Z',有什么办法可以重新压缩它以恢复完全相同的 gzip 文件 Z?在粗略阅读了 DEFLATE 格式后,我猜不会,因为任何给定的文件都可能在 DEF
我必须从数据库向我的邮件 ID 发送一封带有附件的邮件。 EXEC msdb.dbo.sp_send_dbmail @profile_name = 'Adventure Works Admin
我有一个大的 M4B 文件和一个 CUE 文件。我想将其拆分为多个 M4B 文件,或将其拆分为多个 MP3 文件(以前首选)。 我想在命令行中执行此操作(OS X,但如果需要可以使用 Linux),而
快速提问。我有一个没有实现文件的类的项目。 然后在 AppDelegate 我有: #import "AppDelegate.h" #import "SomeClass.h" @interface A
我是一名优秀的程序员,十分优秀!