文件保存/覆盖时读取及读写冲突场景的系统行为解析
文件读写冲突场景的行为分析
一、文件处于保存/覆盖过程中尝试读取的行为
这取决于保存操作的类型和操作系统的文件锁机制:
- 增量/追加式保存:如果写入进程未加排他锁,读取进程大概率会读到不完整的中间数据(比如一半旧内容一半新内容);如果写入进程加了排他锁,读取操作会被阻塞直到锁释放,或直接返回错误(具体取决于系统和调用方式)。
- 覆盖式保存:
- 若采用「临时文件写入后替换原文件」的常见编辑器模式:读取进程会继续读取原文件的旧内容,直到原文件被替换完成,后续重新打开才会获取新内容。
- 若直接截断原文件后写入:读取进程可能读到截断后的空内容+部分新写入数据,或遇到文件大小突变的情况(比如读取到一半文件突然变小)。
二、读取中途遭遇其他进程保存/覆盖的情况
操作系统是否允许该操作?
取决于文件的打开模式和锁策略:
- 默认情况下,读取进程以共享读模式打开文件,大多数操作系统允许其他进程执行写入/覆盖操作,除非写入进程要求排他访问(比如Windows下用独占模式打开,Linux下用
O_EXCL标志),此时写入操作会被阻塞或直接失败。 - 若采用「临时文件替换原文件」的方式,
rename操作在多数文件系统中是原子性的,系统会允许该操作,但原文件的读取句柄不受影响。
读取进程会出现异常吗?
分情况讨论:
- 若为普通增量写入:读取进程不会触发异常,但会读到新旧混合的脏数据。
- 若为直接截断后写入:读取进程在读取到被截断的位置时,会出现读取字节数少于预期的情况(比如
read()返回值小于请求长度),如果代码未处理这种EOF提前的场景,会抛出对应语言的异常(如Python的EOFError)。 - 若为临时文件替换:读取进程不会异常,因为它持有的是原文件的打开句柄,原文件只是被替换而非修改,读取进程会正常读完旧文件的全部内容,直到关闭句柄后重新打开才会看到新文件。
内容的提问来源于stack exchange,提问作者aoiTenshi
相关产品推荐
相关产品推荐

