Java/Unix环境下两进程同时读写同一文件的行为相关问题
场景说明
Java 运行在 UNIX 类操作系统环境下:
- 进程 A 调用
FileOutputStream向磁盘写入文件,写入过程未结束 - 进程 B 同时调用
FileInputStream尝试读取同一个目标文件
问题解答
1. 进程A的写入操作是否会被进程B的读取干扰?
进程A可以正常完成写入,不受影响。
UNIX 系统默认没有强制文件锁机制,Java 标准的 FileOutputStream 实现也不会默认给文件加排他写锁。只要进程A对目标路径有写权限、磁盘剩余空间足够,整个写入流程可以正常执行到底,不会因为有其他进程读取文件就失败。
2. 进程B的读取行为表现
- 不会触发文件锁,也不会抛出
IOException:只要进程B对目标文件有读权限,打开、读取文件的操作都不会报错,Java IO 接口层面不会有异常抛出。 - 大概率读取到不完整的文件内容:进程B读取到的是进程A已经刷入磁盘的数据(包括进程A主动调用
flush()触发落盘,或是操作系统内核自动将缓存的写入数据刷入磁盘的部分)。如果进程B的读取速度快于进程A的写入速度,会在读完当前已落盘的内容后直接拿到EOF(InputStream.read()返回-1),不会感知到后续还有新的内容写入,最终得到的就是不完整的文件。 - 额外最佳实践:如果要避免并发读写读到半写文件,可以让写入进程先写临时文件,写完后再通过
rename系统调用把临时文件重命名为目标文件名。UNIX下rename是原子操作,能保证其他进程要么读到完整的旧版本文件,要么读到完整的新版本文件,不会出现半写的中间状态。
内容的提问来源于stack exchange,提问作者Alexander M.
相关产品推荐
相关产品推荐

